Ruby has the File class that can be initialized using the normal new() method, or using open() and passing a block. How would I write a class that behaved like this?
File.open("myfile.txt","r") do |f|
...
end
The general outline of File.open is something like this:
def open(foo, bar)
f = do_opening_stuff(foo, bar)
begin
yield f
ensure
do_closing_stuff(f)
end
end
It is yield that invokes the block passed by the caller. Putting do_closing_stuff within an ensure guarantees that the file gets closed even if the block raises an exception.
More nitty-gritty on the various ways of calling blocks here: http://innig.net/software/ruby/closures-in-ruby
This is a simple example of passing a block to new/open method
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With