Ruby有File类,可以使用普通new()
方法或使用open()
并传递块来初始化。我怎么写一个表现得像这样的课?
File.open("myfile.txt","r") do |f|
...
end
答案 0 :(得分:3)
File.open的大致如下:
def open(foo, bar)
f = do_opening_stuff(foo, bar)
begin
yield f
ensure
do_closing_stuff(f)
end
end
调用调用者传递的块是yield
。将do_closing_stuff
置于ensure
内可确保即使该块引发异常也会关闭该文件。
有关调用块的各种方法的更多细节:http://innig.net/software/ruby/closures-in-ruby
答案 1 :(得分:3)
这是将块传递给new/open
方法
class Foo
def initialize(args, &block)
if block_given?
p block.call(args) # or do_something
else
#do_something else
end
end
def self.open(args, &block)
if block_given?
a = new(args, &block) # or do_something
else
#do_something else
end
ensure
a.close
end
def close
puts "closing"
end
end
Foo.new("foo") { |x| "This is #{x} in new" }
# >> "This is foo in new"
Foo.open("foo") { |x| "This is #{x} in open" }
# >> "This is foo in open"
# >> closing
答案 2 :(得分:1)
您可以创建一个创建实例的类方法yield
,然后在yield
之后执行清理。
class MyResource
def self.open(thing, otherthing)
r = self.new(thing, otherthing)
yield r
r.close
end
def initialize(thing, otherthing)
@thing = thing
@otherthing = otherthing
end
def do_stuff
puts "Doing stuff with #{@thing} and #{@otherthing}"
end
def close
end
end
现在,您可以将它与构造函数一起使用:
r = MyResource.new(1, 2)
r.do_stuff
r.close
或使用一个自动close
对象的块:
MyResource.open(1, 2) do |r|
r.do_stuff
end