From: ara.t.howard@... Date: 2006-05-09T04:23:39+09:00 Subject: ml style 'let' impl - fun with metaprogramming... i was just playing with this - an ml style let for ruby: harp:~ > cat a.rb require 'let' # # let allows you to setup local variables that will only be in scope for the # following block in an ml style # let :list => [] do list << 42 p list # => [42] end # # you can, of course, nest blocks # let :list => [] do list << 'forty-two' let :list => [] do list << 42 p list # => [42] end p list # => ['forty-two'] end # # the return value of let allows one to get a handle on the context to # retrieve values later if needed. # context = let :a => nil, :b => nil do self.a = 4 self.b = 2 end p [context.a, context.b] # [4, 2] # # note that the special variable '_' is a shorthand for 'self' inside the # block. # context = let :a => nil, :b => nil do _.a = 4 _.b = 2 end p [context.a, context.b] # [4, 2] # # 'open' getter/setters are allowed # context = let :a => nil, :b => nil do a 4 b 2 end p [context.a, context.b] # [4, 2] # # 'let' params may be a list or hash. iff list values default to nil. # context = let(:a, :b => 2){ a 4 } p [context.a, context.b] # [4, 2] harp:~ > ruby a.rb [42] [42] ["forty-two"] [4, 2] [4, 2] [4, 2] [4, 2] harp:~ > cat let.rb def let *argv, &b #--{{{ hashes, list = argv.partition{|arg| Hash === arg} hashes.inject(h={}){|h,h2| h.update h2} list.each{|elem| h[elem] = nil} blank_slate = Class.new{ %w( inspect instance_eval instance_variable_get instance_variable_set ).each do |m| alias_method "__#{ m }__", "#{ m }" end instance_methods.each{|m| m !~ %r/^__/ and undef_method m} def _(); @_ ||= self; end h.each do |k,v| get, set, iff, var = "#{ k }", "#{ k }=", "#{ k }?", "@#{ k }" define_method(get) do |*argv| case argv.size when 0 unless eval("defined? #{ var }") __instance_variable_set__ var, v end __instance_variable_get__ var when 1 __send__ set, *argv else raise ArgumentError, "#{ argv.size } instead of 0 or 1" end end define_method(set) do |arg| __instance_variable_set__ var, arg end alias_method iff, get end }.new blank_slate.__instance_eval__ &b blank_slate #--}}} end it's kind of fun but perhaps not incredibly useful. thoughts? -a -- be kind whenever possible... it is always possible. - h.h. the 14th dali lama