Forum: Ruby ml style 'let' impl - fun with metaprogramming...

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-05-08 21:24
(Received via mailing list)
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
5d15f83f0e681b138d95f1ec430868fa?d=identicon&s=25 Joey (Guest)
on 2006-05-08 21:42
(Received via mailing list)
This topic is locked and can not be replied to.