Hi --

On Sat, 14 Nov 2009, James Brister wrote:

> I'm trying to do something similar to the Camping 'R' class generator.
> Can anyone explain to me how to get the following to print out from the
> program below:
>
>     param is p and arg is this is a P
>     param is q and arg is this is a Q
>
> (basically I want to capture the argument to the maker functions inside
> the class they generate).
>
> ---- cut here --- cut here --- cut here ---
>
> ## Using this function causes a blank after "arg is"
> def maker1(thearg)
>  Class.new do
>    @arg = thearg.dup
>    def self.argval
>      @arg
>    end
>    def doit(param)
>      puts "param is #{param} and arg is #{self.class.argval}"
>    end
>  end
> end

Instance variables are strictly per object. The class you get back
from maker1 is not the same object as any of its subclasses.

> ## Using this function causes the same value to be printed out for all
> classes
> def maker2(thearg)
>  Class.new do
>    @@arg = thearg.dup
>    def doit(param)
>      puts "param is #{param} and arg is #{@@arg}"
>    end
>  end
> end

Class variables are weird :-)

> ## using this function causes a undefined 'local variable or method'
> def maker3(thearg)
>  Class.new do
>    def doit(param)
>      puts "param is #{param} and arg is #{thearg}"
>    end
>  end
> end

The def keyword starts a new scope.

However... the define_method method doesn't:

   def maker3(thearg)
     Class.new do
       define_method(:doit) do |param|
         puts "param is #{param} and arg is #{thearg}"
       end
     end
   end

In this version, I'm using only code blocks (and no 'def's). Code
blocks do see the local variables that exist at the point where the
code block starts. So thearg is in scope. Also, the block you provide
to define_method becomes, basically, the body of the method. I define
it to take one argument (note: the parameter syntax and binding
semantics for this have changed in Ruby 1.9, but they've actually
changed in a way that makes blocks and methods more rather than less
congruent), and of course that argument is in scope too.


David

-- 
The          Ruby training with D. Black, G. Brown, J.McAnally
Compleat     Jan 22-23, 2010, Tampa, FL
Rubyist      http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)