--------------040607070405050105040600 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit stevetuckner wrote: > I often use the || diom in ruby for late initialization. But was > recently looking for an idiom that would allow me to overwrite a > variable if the right side is defined without repeating myself. > > I have used the following: > > var al if val > > but I have to repeat val and that violates DRY. [...] > Any ideas out there? require 'binding_of_caller' def and_set(name, value) return if value.nil? Binding.of_caller do |context| eval("#{name} bjectSpace._id2ref(#{value.id})", context) end end and_set(:var, val) Not sure if you were looking for this kind of solution though. :) Regards, Florian Gross --------------040607070405050105040600 Content-Type: text/plain; nameinding_of_caller.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filenameinding_of_caller.rb" begin require 'simplecc' rescue LoadError def Continuation.create(*args, &block) cc il; result allcc {|c| cc ; block.call(cc) if block and args.empty?} result || rgs return *[cc, *result] end end # This method returns the binding of the method that called your # method. It will raise an Exception when you're not inside a method. # # It's used like this: # def inc_counter # Binding.of_caller do |binding| # eval("counter + ", binding) # end # end # counter # 2.times { inc_counter } # counter # 2 # # You will have to put the whole rest of your method into the # block that you pass into this method. If you don't do this # an Exception will be raised. Because of the way that this is # implemented it has to be done this way. If you don't do it # like this it will raise an Exception. def Binding.of_caller(&block) old_critical hread.critical Thread.critical rue count cc, result, error, extra_data ontinuation.create(nil, nil) error.call if error tracer ambda do |*args| type, context, extra_data rgs[0], args[4], args if type "return" count + # First this method and then calling one will return -- # the trace event of the second event gets the context # of the method which called the method that called this # method. if count 2 # It would be nice if we could restore the trace_func # that was set before we swapped in our own one, but # this is impossible without overloading set_trace_func # in current Ruby. set_trace_func(nil) cc.call(eval("binding", context), nil, extra_data) end elsif type ! line" set_trace_func(nil) error_msg Binding.of_caller used in non-method context or " + "trailing statements of method using it aren't in the block." cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil) end end unless result set_trace_func(tracer) return nil else Thread.critical ld_critical case block.arity when 1 then yield(result) else yield(result, extra_data) end end end --------------040607070405050105040600--