2016-06-15 100 views
4

我是Ruby的新手,我正在研究一個涉及到使用它的項目。 Go提供了defer聲明,我想知道如何在ruby中複製該函數。Go defer的ruby等價物是什麼?

例子:

dst, err := os.Create(dstName) 
if err != nil { 
    return 
} 
defer dst.Close() 

回答

8

沒有適當等同於紅寶石defer語句,但是如果你想確保一個特定的代碼塊被執行,則可以使用ensure聲明。不同的是,你不能像延遲那樣堆棧代碼塊,但結果是一樣的。

在塊

begin 
    # ... 
ensure 
    # This code will be executed even if an exception is thrown 
end 

在方法

def foo 
    # ... 
ensure 
    # ... 
end 

Object#ensure標記的開始/結束塊的最終,可選的子句, 通常在情況下,塊還包含一個救援條款。確保子句中的 代碼保證執行,無論是否有 控制流向救援塊。

0

它沒有這樣的說法,但您可以使用元編程來獲得此行爲。

module Deferable 
    def defer &block 
    @defered_methods << block 
    end 

    def self.included(mod) 
    mod.extend ClassMethods 
    end 

    module ClassMethods 
    def deferable method 
     original_method = instance_method(method) 
     define_method(method) do |*args| 
     @@defered_method_stack ||= [] 
     @@defered_method_stack << @defered_methods 
     @defered_methods = [] 
     begin 
      original_method.bind(self).(*args) 
     ensure 
      @defered_methods.each {|m| m.call } 
      @defered_methods = @@defered_method_stack.pop 
     end 
     end 
    end 
    end 
end 

class Test 
    include Deferable 

    def test 
    defer { puts "world" } 
    puts "hello" 
    end 

    def stacked_methods str 
    defer { puts "and not broken" } 
    defer { puts "at all" } 
    puts str 
    test 
    end 

    def throw_exception 
    defer { puts "will be executed even if exception is thrown" } 
    throw Exception.new 
    end 

    deferable :test 
    deferable :stacked_methods 
    deferable :throw_exception 
end 

調用示例:

t = Test.new 
t.test 

# -> Output: 
# hello 
# world 

t.stacked_methods "stacked methods" 

# -> Output: 
# stacked methods 
# hello 
# world 
# and not broken 
# at all 

t.throw_exception 
# -> Output: 
# will be executed even if exception is thrown 
# deferable.rb:45:in `throw': uncaught throw #<Exception: Exception> (UncaughtThrowError) 
#   from deferable.rb:45:in `throw_exception' 
#   from deferable.rb:18:in `call' 
#   from deferable.rb:18:in `block in deferable' 
#   from deferable.rb:59:in `<main>' 
+0

有人downvoted這一點。爲什麼?這段代碼不起作用嗎?有沒有醜陋的後果?這看起來合法和整齊。 – Narfanator

相關問題