Ruby: passing blocks as parameters from oustide class

I am getting below error when executing code:

example.rb:9:in `<main>': undefined method `each' for main:Object (NoMethodError)

Line 9 is second last line in my code.

My code:

class TargetProvider
  def each(target,&block)
    block.call(target)
  end   
end

tp = TargetProvider.new
each { puts "Hello!" }
tp.each(1, each)

My motive is to call block with target parameter.

How can I pass a block outside class. Any help please.

2 answers

  • answered 2017-06-17 19:33 Egor Biriukov

    Well, the problem is here:

    tp = TargetProvider.new
    each { puts "Hello!" } # Here
    tp.each(1, each)
    

    Here, you are calling each method, not declaring a new variable. In Ruby, if you call a method without specifying its object (via object.method), interpreter searches for that method in MainObject.

    It's clear that there no such method in it, so that's what an error is about.

    What you may want to achieve is looks like this:

    tp = TargetProvider.new
    tp.each(1) { puts "Hello!" }
    

    That code calls TargetProvider's each method passing it a block.

  • answered 2017-06-17 19:33 Fede

    Here is yout code:

    class TargetProvider
      def each(target,&block)
        block.call(target)
      end   
    end
    
    tp = TargetProvider.new
    each { puts "Hello!" } # this line is trying to run a method called each
    tp.each(1, each)
    

    You need to define a lambda or a proc and store it in a variable, or use the implicit block of the each. Here is an example using a lambda:

    class TargetProvider
      def each(target,&block)
        block.call(target)
      end   
    end
    
    tp = TargetProvider.new
    each_block = lambda { |a| puts "Hello!" }
    tp.each(1, &each_block)
    

    Here is an example using the implicit block:

    class TargetProvider
      def each(target,&block)
        block.call(target)
      end   
    end
    
    tp = TargetProvider.new
    each_block = lambda { |a| puts "Hello!" }
    tp.each(1) { puts "Hello!" }