Nikolay Lipovtsev
Nikolay Lipovtsev

Reputation: 679

Performing the same code block (yield)

How can I make sure that the method is executed once. If method A is inserted inside the method Ai as a block to the secondary methods are is not performed. Something like this:

def a
  puts "|start|"
  yield
  puts "|end|"
end

a do
  a { "|test_one|" }
  a { "|test_two|" }
end

=> "|start||test_one||test_two||end|"

Not like this:

=> "|start|test_one|start|end|test_two|end|"

Upvotes: 1

Views: 61

Answers (3)

Taha Husain
Taha Husain

Reputation: 312

You're calling method a but not printing the block that is been yielded.

yield replaces the whole block that has been passed as an argument, inside the method where it is written.

so your method actually becomes like this when ruby interprets the code.

  puts "|start|"
  puts "|start|" # 
  "|test_one|"   # replaced for yield on call `a {"|test_one|"}`
  puts "|end|"   #
  puts "|start|" #
  "|test_two|"   # replaced for yield on call `a {"|test_two|"}`
  puts "|end|"   #
  puts "|end|"

Output:

|start||start||end||start||end||end|

If you want to see if what the block is returning then add a puts before yield

def a
  puts "|start|"
  puts yield
  puts "|end|"
end

Then call your method the same way and now the output will be.

|start||start||test_one||end||start||test_two||end||end|

Correct me if I'm missing anything.

Upvotes: 0

Grych
Grych

Reputation: 2901

In your example the method a will run three times, because you execute it once in a main part and two time in a block. To have a desired output, you don't have to run this method in a block. Just execute the block which contains two instructions:

irb(main):066:0> a do
irb(main):067:1*   puts "|test_one|"
irb(main):068:1>   puts "|test_two|"
irb(main):069:1> end
|start|
|test_one|
|test_two|
|end|

Upvotes: 0

Hector Correa
Hector Correa

Reputation: 26690

In your current example you are calling your function a recursively twice.

If you change your code as follow it will execute the block only once and get the output that you describe:

def a
  puts "|start|"
  yield
  puts "|end|"
end

a do
  puts "|test_one|"
  puts "|test_two|"
end

Upvotes: 1

Related Questions