Question

I want to write a code that satisfies:

SomeClass.new.execute(method) == 3

and I have:

class SomeClass
  def execute(method)
    def method
     yield
    end
  end
end

method = 1+2

which gives me nil. I'm still very confused about yield. Any help is greatly appreciated.

Was it helpful?

Solution

You're along the right lines, but your parameter method must be a code block.

You can create a code block in a few different ways. The most common is anonymously, using {...} or do...end. If you want to store the code block in a variable, which you'd need to do to call SomeClass.new.execute(method), you can use Proc.new.

There are other ways of creating blocks (using the lambda syntax), but they are beyond the scope of this question.

This will work using a block stored in a variable:

class SomeClass
  def execute
    yield
  end
end

method = Proc.new { 1+2 }
SomeClass.new.execute(&method) # => 3

Or, more succinctly,

SomeClass.new.execute { 1 + 2 } # => 3

OTHER TIPS

You're sort of in the right direction-ish. yield will execute a passed-in block. So you want to do something like this:

class SomeClass
  def execute
    yield
  end
end

And then you can call it like this:

SomeClass.new.execute { 1+2 }

The yield keyword passes control to any block that was passed to the method. You haven't passed any blocks, so there's nothing to do.

You want something like this:

class C
  def execute
    yield    # Pass control to a block that was passed in.
             # Method returns whatever the value of evaluating `b` was.
  end
end

Now you can do:

C.new.execute { 1 + 2 }     # Pass block containing a statement "1 + 2".
# => 3                      # The result of evaluating "1 + 2" is
                            #   returned from the #execute method.

If you want to pass a method object corresponding to the block you want to pass, instead of specifying it anonymously, you can make a lambda:

b = lambda { 1 + 2 }
C.new.execute &b            # Pass an object to #execute that will be used as
# => 3                      #   the block.

Ruby has a few mostly-equivalent ways of making lambdas:

lambda { 1 + 2 }
Proc.new { 1 + 2 }
-> { 1 + 2 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top