Reputation: 1283
class SomeClass
def initialize
yield
end
def test
puts 'test'
end
end
I want to execute the test function inside a block when I initialize a some SomeClass. SomeClass.new { test() } This gives me
NoMethodError: undefined method `test' for main:Object
Upvotes: 1
Views: 124
Reputation: 76
Two solutions:
class SomeClass
def initialize(&block)
instance_eval(&block)
end
def test
puts 'test'
end
end
SomeClass.new { test() } #=> test
class SomeClass
def initialize
yield self
end
def test
puts 'test'
end
end
SomeClass.new {|o| o.test() } #=> test
Some references hope to help you:
1.instance_eval no longer yielding self in ruby 1.9: https://www.ruby-forum.com/topic/189422
2.How do I build DSLs with yield and instance_eval?: http://rubylearning.com/blog/2010/11/30/how-do-i-build-dsls-with-yield-and-instance_eval/
Upvotes: 0
Reputation: 118261
It is very easy, just pass the self
:
class SomeClass
def initialize
yield self if block_given?
end
def test
puts 'test'
end
end
SomeClass.new { |ob| ob.test }
# >> test
Your one didn't work, because blocks are closure, and the self
is set to main
inside the block in your example. main
is a instance of Object
. You didn't defie the #test
inside the Object
, so main
tries to call the #test
and you got the genuine error.
Upvotes: 3
Reputation: 8212
Or you can use call, like this:
class SomeClass
def initialize(&block)
block.call(self) if block_given?
end
def test
puts 'test'
end
end
SomeClass.new {|s| s.test }
Upvotes: 2
Reputation: 44675
You are looking for instance_eval
:
class SomeClass
def initialize(&block)
instance_eval(&block) if block_given?
end
def test
puts 'test'
end
end
SomeClass.new { test() } #=> test
Upvotes: 3