Adding instance methods to class at runtime

(Jon A. Lambert) #1

I want to add instance methods to a class at runtine.

$ cat testcmds.rb
module Bar
  def hello
    puts "hello called"
  end
end

class Foo
end

Foo.include(Bar)

Foo.new.hello

$ ruby testcmds.rb
testcmds.rb:10: private method `include' called for Foo:Class (NoMethodError)

How can I do this?

(David A. Black) #2

Hi --

I want to add instance methods to a class at runtine.

There's no other time to do it :slight_smile:

$ cat testcmds.rb
module Bar
def hello
  puts "hello called"
end

class Foo
end

Foo.include(Bar)

You can reopen the class and do the include:

   class Foo
     include Bar
   end

or you can use send:

   Foo.send("include", Bar)

David

···

On Tue, 30 Aug 2005, Jon A. Lambert wrote:

--
David A. Black
dblack@wobblini.net

(Kirk Haines) #3

irb(main):013:0* Foo.send(:include, Bar)
=> Foo
irb(main):014:0> Foo.new.hello
hello called

Kirk Haines

···

On Monday 29 August 2005 2:52 pm, Jon A. Lambert wrote:

I want to add instance methods to a class at runtine.

$ cat testcmds.rb
module Bar
  def hello
    puts "hello called"
  end
end

class Foo
end

Foo.include(Bar)

Foo.new.hello

$ ruby testcmds.rb
testcmds.rb:10: private method `include' called for Foo:Class
(NoMethodError)

How can I do this?

(Jon A. Lambert) #4

David A. Black wrote:

or you can use send:

  Foo.send("include", Bar)

Excellent Thank you.
I think my problem was scope then.
Here's what I be doing and it now works like a charm.

$ cat cmd1/cmd_bar.rb module Command
  def cmd_bar
    puts "cmd_bar one called"
  end
end

$ cat cmd2/cmd_bar.rb module Command
  def cmd_bar
    puts "cmd_bar two called"
  end
end

$ cat testcmds.rb

class Foo
end

def load1
  cmds = Dir.glob("cmd1/cmd_*.rb")
  cmds.each {|c| load(c)}
  Foo.send(:include,Command)
end

def load2
  cmds = Dir.glob("cmd2/cmd_*.rb")
  cmds.each {|c| load(c)}
  Foo.send(:include,Command)
end

f = Foo.new

load1
f.cmd_bar

load2
f.cmd_bar

$ ruby testcmds.rb cmd_bar one called
cmd_bar two called

···

--
J. Lambert