user3814030
user3814030

Reputation: 1283

yield in to a block with call function

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

Answers (4)

blackanger
blackanger

Reputation: 76

Two solutions:

1

  class SomeClass    

    def initialize(&block)
      instance_eval(&block)
    end

    def test
      puts 'test'
    end 
  end

  SomeClass.new { test() }    #=> test

2

  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

Arup Rakshit
Arup Rakshit

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

ReggieB
ReggieB

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

BroiSatse
BroiSatse

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

Related Questions