Cla*_*diu 12 ruby python language-features with-statement control-flow
在Python中,该with
语句用于确保始终调用清理代码,无论抛出异常还是返回函数调用.例如:
with open("temp.txt", "w") as f:
f.write("hi")
raise ValueError("spitespite")
Run Code Online (Sandbox Code Playgroud)
在这里,即使引发了异常,文件也会关闭.这里有一个更好的解释.
Ruby中有这个构造的等价物吗?或者你可以编写一个代码,因为Ruby有延续吗?
Jör*_*tag 22
Ruby对文字匿名过程(在Ruby中称为块)具有语法轻量级支持.因此,它不需要新的语言功能.
(一般来说,如果你需要添加语言功能,这是一个不好的标志.你应该能够在库中实现所有内容,否则它是语言设计不良的标志.)
所以,你通常做的是编写一个方法,它接受一段代码,分配资源,在该资源的上下文中执行代码块,然后关闭资源.
像这样的东西:
def with(klass, *args)
yield r = klass.open(*args)
ensure
r.close
end
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
with File, 'temp.txt', 'w' do |f|
f.write 'hi'
raise 'spitespite'
end
Run Code Online (Sandbox Code Playgroud)
但是,这是一种非常程序化的方法.Ruby是一种面向对象的语言,这意味着在a的上下文中正确执行代码块的责任File
应属于File
该类:
File.open 'temp.txt', 'w' do |f|
f.write 'hi'
raise 'spitespite'
end
Run Code Online (Sandbox Code Playgroud)
这可以实现如下:
def File.open(*args)
f = new(*args)
return f unless block_given?
yield f
ensure
f.close if block_given?
end
Run Code Online (Sandbox Code Playgroud)
这是一个通用模式,由Ruby核心库,标准库和第三方库中的许多类实现.
与通用Python上下文管理器协议的更紧密的对应关系是:
def with(ctx)
yield ctx.setup
ensure
ctx.teardown
end
class File
def setup; self end
alias_method :teardown, :close
end
with File.open('temp.txt', 'w') do |f|
f.write 'hi'
raise 'spitespite'
end
Run Code Online (Sandbox Code Playgroud)
请注意,这几乎与Python示例无法区分,但它不需要在语言中添加新语法.
Ruby中的等价物是将块传递给File.open方法.
File.open(...) do |file|
#do stuff with file
end #file is closed
Run Code Online (Sandbox Code Playgroud)
这是Ruby使用的成语,也是你应该习惯的成语.
归档时间: |
|
查看次数: |
4144 次 |
最近记录: |