Reputation: 5745
I am trying to define an instance method on Foo, how do I do that, I keep getting method undefined errors for define_method and define_instance_method
?
Also, why would I use define_method
vs define_instance_method
?
class Foo
def boo
self.instance_variable_set('@a', "help") # => "help"
end # => :boo
def voo
self.instance_variable_get('@a') # => "help"
end # => :voo
def noo
define_method 'goo' do # ~> NoMethodError: undefined method `define_method' for #<Foo:0x00007fce1309e000 @a="help">\nDid you mean? define_singleton_method
"goo"
end
end # => :noo
def woo
define_instance_method 'qoo' do # ~> NoMethodError: undefined method `define_instance_method' for #<Foo:0x00007feacb98e780 @a="help">\nDid you mean? define_singleton_method
"qoo"
end
end # => :woo
end # => :woo
Upvotes: 1
Views: 1520
Reputation: 10054
There's Module#define_method
and there's Object#define_singleton_method
. There is no #define_instance_method
.
Module#define_method
allows you to define an instance method on the receiving module or class, which is analogous to a def
:
class A
def foo
123
end
end
A.define_method(:bar) { 456 }
A.new.foo # => 123
A.new.bar # => 456
You cannot use it on other type of objects, such as instances of A
, which are of type A
, only on Module
or Class
:
A.new.define_method(:bogus) { 'oops' }
# => NoMethodError (undefined method `define_method' for #<A:0x00007ffa6c0c77e0>)
Object#define_singleton_method
, on the other hand, can be used on any Object
, including Class
and Module
. It allows you to create a method on the receiver. For a class or module, that's equivalent to defining a class method:
class B
def self.x
'x'
end
class << self
def y
'y'
end
end
end
B.define_singleton_method(:z) { 'z' }
B.x # => 'x'
B.y # => 'y'
B.z # => 'z'
But we can also use it directly on an instance of a class to add a method to that very instance:
class C; end
c = C.new
c.define_singleton_method(:foo) { 'hello' }
c.foo # => 'hello'
C.new.foo # => NoMethodError (undefined method `foo' for #<C:0x00007ff95f0e4038>)
C.foo # => NoMethodError (undefined method `foo' for C:Class)
Upvotes: 3
Reputation: 1012
Module#define_method
is a private method and also a class method.Your one didn't work,as you tried to call it on the instance of foo class.You have to call it like this:
class Foo
def noo
self.class.send(:define_method,'goo') { puts 'Goo'}
end
end
Upvotes: 0