Forum: Ruby define_method inside a module

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.
MR D. (Guest)
on 2008-10-18 15:59
hi,

I am trying to use some dynamic features of ruby.

Inside my module, I try to add some method dynamicaly but I get an error
when I am trying to.



module Rubyhaviour
  def add(object)
    name = "@" + object.class.downcase

    if self.instance_variable_get(name)
      self.instance_variable_get(name) << object
    else
      self.instance_variable_set(name, Array.new)
      self.instance_variable_get(name) << object

      define_method(name) do
        instance_variable_get("@#{name}")
      end
    end
  end
end
undefined method `define_method' for #<Test:0x2ce631c> (NoMethodError)
MR D. (Guest)
on 2008-10-18 16:00
MR Damien wrote:
> hi,
>
> I am trying to use some dynamic features of ruby.
>
> Inside my module, I try to add some method dynamicaly but I get an error
> when I am trying to.
>
>
>
> module Rubyhaviour
>   def add(object)
>     name = "@" + object.class.downcase
>
>     if self.instance_variable_get(name)
>       self.instance_variable_get(name) << object
>     else
>       self.instance_variable_set(name, Array.new)
>       self.instance_variable_get(name) << object
>
>       define_method(name) do
>         instance_variable_get("@#{name}")
>       end
>     end
>   end
> end
> undefined method `define_method' for #<Test:0x2ce631c> (NoMethodError)

I pushed enter too fast, here are the missing code

class Test
  include Rubyhaviour
end

test = test.add(some_object)
Then I get "undefined method `define_method' for #<Test:0x2ce631c>
(NoMethodError)"
Joel VanderWerf (Guest)
on 2008-10-18 22:55
(Received via mailing list)
MR Damien wrote:
>   def add(object)
>       end
>     end
>   end
> end
> undefined method `define_method' for #<Test:0x2ce631c> (NoMethodError)

Try working in the singleton class:

class C
   def foo
     class << self
       define_method :bar do puts "BAR"; end
     end
   end
end

c = C.new
c.foo
c.bar
MR D. (Guest)
on 2008-10-20 11:57
Joel VanderWerf wrote:
> MR Damien wrote:
>>   def add(object)
>>       end
>>     end
>>   end
>> end
>> undefined method `define_method' for #<Test:0x2ce631c> (NoMethodError)
>
> Try working in the singleton class:
>
> class C
>    def foo
>      class << self
>        define_method :bar do puts "BAR"; end
>      end
>    end
> end
>
> c = C.new
> c.foo
> c.bar

Hi,

seems not to work neither


------------------
def add(object)
    name = "@" + self.collection_name_for(object)

    if self.instance_variable_get(name)
      self.instance_variable_get(name) << object
    else
      self.instance_variable_set(name, Array.new)
      self.instance_variable_get(name) << object

      class << self
        define_method(name) do
          instance_variable_get("@#{name}")
        end
      end

    end
  end
------------------
in `define_method': interning empty string (ArgumentError)
David A. Black (Guest)
on 2008-10-20 15:20
(Received via mailing list)
Hi --

On Mon, 20 Oct 2008, MR Damien wrote:

>>
>> c.bar
>    if self.instance_variable_get(name)
>
>    end
>  end
> ------------------
> in `define_method': interning empty string (ArgumentError)

That's because name is not in scope inside the class definition body
(class << self). In order to keep name in scope, you need to use
class_eval on the singleton class. That way, you're operating inside a
code block, which does share the local variables.

   (class << self; self; end).class_eval do
     define_method(name) do

etc.


David
Robert K. (Guest)
on 2008-10-20 15:44
(Received via mailing list)
2008/10/20 David A. Black <removed_email_address@domain.invalid>:
>>>>    end
>>>     end
>>
>>
>
> That's because name is not in scope inside the class definition body
> (class << self). In order to keep name in scope, you need to use
> class_eval on the singleton class. That way, you're operating inside a
> code block, which does share the local variables.
>
>  (class << self; self; end).class_eval do
>    define_method(name) do

Also, watch closely the contents of "name" and how you (OP) use it.

robert
MR D. (Guest)
on 2008-10-23 12:53
Thanks for you answers, I will check that.
This topic is locked and can not be replied to.