我是Ruby的新手,我正在研究一個涉及到使用它的項目。 Go提供了defer
聲明,我想知道如何在ruby中複製該函數。Go defer的ruby等價物是什麼?
例子:
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
我是Ruby的新手,我正在研究一個涉及到使用它的項目。 Go提供了defer
聲明,我想知道如何在ruby中複製該函數。Go defer的ruby等價物是什麼?
例子:
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
沒有適當等同於紅寶石defer
語句,但是如果你想確保一個特定的代碼塊被執行,則可以使用ensure
聲明。不同的是,你不能像延遲那樣堆棧代碼塊,但結果是一樣的。
在塊
begin
# ...
ensure
# This code will be executed even if an exception is thrown
end
在方法
def foo
# ...
ensure
# ...
end
Object#ensure標記的開始/結束塊的最終,可選的子句, 通常在情況下,塊還包含一個救援條款。確保子句中的 代碼保證執行,無論是否有 控制流向救援塊。
它沒有這樣的說法,但您可以使用元編程來獲得此行爲。
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>'
有人downvoted這一點。爲什麼?這段代碼不起作用嗎?有沒有醜陋的後果?這看起來合法和整齊。 – Narfanator