>> 2) you have to be careful with interpolation, in any case, as there are

> > scope changes to watch out for.
>
> Can you elaborate on this?
>

Sure.  You can do this, and it works:

x = [1,2,3]
class << x
    def sum_of_squares
        collect { |x| x*x }.inject { |a,b| a+b }
    end
end

p x.sum_of_squares
p x.sum_of_squares

But if you do "the same thing" with class_eval / define_method:

x = [1,2,3]
x_eigenclass = (class <<x; self; end)
x_eigenclass.class_eval {
    define_method("sum_of_squares") {
        collect { |x| x*x }.inject { |a,b| a+b }
    }
}

p x.sum_of_squares
p x.sum_of_squares

it fails the second time because the blocks are closures of the outer scope
and the "x" in the inner loop is the same as the "x" in the enclosing scope,
and so the second time you do "x.sum_of_squares" x is 3, not your augmented
array.

Now, this can be handy in a case such as yours where you want to construct
method names, but you have to be aware that the scopes aren't the same as
they are with "normal" methods, where locals are always...local.

There are other ways to do it, for example:

x = [1,2,3]
f_to_sum = "x*x"
f_name = "sum"
eval %Q{
    class << x
        def #{f_name}_of_squares
            collect { |x| #{f_to_sum} }.inject { |a,b| a+b }
        end
    end
}

p x.sum_of_squares
p x.sum_of_squares

...each with their own advantages and pitfalls.


>
> > 3) class_eval/define_method add quite a few wrinkles over class/def
> > (which are after all executable, and can be run dynamically).
>
> It doesn't seem possible to say:
> def <code here that gives a method name>
> end
>
> So I'll have to use define_method.
>

Or you could (getting a little evil here) do this:

def brices_unique_temporary_method_name(arg1,arg2)
    puts "You passed in #{arg1} and #{arg2}"
end

alias_method(target_method,"brices_secret_backup_of#{target_method}")
alias_method("brices_unique_temporary_method_name",target_method)
remove_method("brices_unique_temporary_method_name")

I'm also concerned by the performance penalty paid when redefining a
> method like this...
>

Hmm.  Once you've done it shouldn't be any worse than any normal method, I
would think.  Except for the effect on your karma, I mean.

-- M
-----------------------------------------------------------
When in trouble or in doubt, run in circles,
scream and shout. -- 1920's parody of the
maritime general prudential rule
------------------------------------------------------------

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to puppet-dev@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to