Timothy Hunter wrote: > Daniel Schierbeck wrote: >> Sche Daniel wrote: >>> Hello all, >>> >>> open is singleton method of File and can be used in two ways >>> >>> # 1 way >>> f = File.open("data") >>> f.readline until f.lineno == 10 >>> puts f.readline >>> f.close >>> >>> # 2 way >>> File.open("data") do |f| >>> f.readline until f.lineno == 10 >>> puts f.readline >>> end >>> >>> I am trying to mimic this with my own classes >>> >>> irb(main):001:0> class Resource >>> irb(main):002:1> @@cnt=0 >>> irb(main):003:1> def initialize >>> irb(main):004:2> @id = @@cnt >>> irb(main):005:2> @@cnt += 1 >>> irb(main):006:2> end >>> irb(main):007:1> def id;@id;end >>> irb(main):008:1> end >>> => nil >>> irb(main):009:0> class Q >>> irb(main):010:1> def Q.get &block >>> irb(main):011:2> r = Resource.new >>> irb(main):012:2> if Kernel::block_given? >>> irb(main):013:3> block.call(r) >>> irb(main):014:3> else >>> irb(main):015:3* return r >>> irb(main):016:3> end >>> irb(main):017:2> end >>> irb(main):018:1> end >>> => nil >>> irb(main):019:0> Q.get >>> => #<Resource:0x40206fe0 @id=0> >>> irb(main):020:0> Q.get {|r| puts r.id} >>> 1 >>> => nil >>> irb(main):021:0> >> >> First off, you can make it more efficient if your use `yield' instead >> of calling the block explicitly: >> >> class Q >> def self.get >> if block_given? >> yield Resource.new >> else >> Resource.new >> end >> end >> end >> >> The above is what I'd go with, but there a lots of ways to accomplish >> what you want. Take this for example: >> >> class Q >> def self.get >> yield resource = Resource.new >> rescue LocalJumpError >> resource >> end >> end >> >> or even shorter (though it'll catch other exceptions as well, so you >> have to be careful) >> >> class Q >> def self.get >> yield(resource = Resource.new) rescue resource >> end >> end >> >> >> Cheers, >> Daniel >> > There's no need to golf this. There's a well-known idiom for coding > block-scoped resources. See the section entitled "Destroy this object > when it goes out of scope" at > http://wiki.rubygarden.org/Ruby/page/show/RubyIdioms. Here's the example > from that page: > > def Resource.open( identifier ) # :yield: resource > resource = Resource.new( identifier ) > if block_given? > begin > yield resource > ensure > resource.close > end > else > return resource > end > end > > > The benefit of using the standard idiom is that any Ruby programmer that > reads your code will instantly understand what it's doing. Coding it any > other way will likely cause a bit of confusion. And, of course, if you > don't use the idiom you might forget the "ensure" part. I don't think the original post mentioned that the resource needed to be closed :) I thought he wanted an easy way to either yield or return. But yes, for that wider problem, your code is superior. We were just answering different questions. Cheers, Daniel