Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Ruby Blocks Ruby Blocks Calling Blocks

Why I cant print the returning value of the block method?

Hi! I'm trying to directly printing the returning value of the block method "run". This code runs without issues:

class Benchmarker
  def run(description, &block)
    start_time = Time.now
    block.call
    end_time = Time.now
    elapsed = end_time - start_time
    puts
    return "#{elapsed} seconds elapsed for #{description}"
  end
end

benchmarker = Benchmarker.new
result = benchmarker.run "sleeping random amount of time" do
  5.times do
    print "."
    sleep(rand(0.1..1.0))
  end
end

puts result

but if I try to print directly the result of the block method:

class Benchmarker
  def run(description, &block)
    start_time = Time.now
    block.call
    end_time = Time.now
    elapsed = end_time - start_time
    puts
    return "#{elapsed} seconds elapsed for #{description}"
  end
end

benchmarker = Benchmarker.new
puts benchmarker.run "sleeping random amount of time" do
  5.times do
    print "."
    sleep(rand(0.1..1.0))
  end
end

I got this error:

in `run': undefined method `call' for nil:NilClass (NoMethodError)
    from benchmarker.rb:13:in `<main>'

2 Answers

Kourosh Raeen
Kourosh Raeen
23,733 Points

Hi Francesco - Here's the syntax that works:

puts benchmarker.run("sleeping random amount of time") {
  5.times do
    print "."
    sleep(rand(0.1..1.0))
  end
}

Don't ask me why this works and not yours because I don't have a good answer as of now :smiley:, but it seems like with your syntax the block is not passed into the function so you end up calling the call method, pardon the pun, on nil. If you find a good answer let me know.

If you do the following:

class Benchmarker
  def run(description, &block)
    start_time = Time.now
    block.call
    end_time = Time.now
    elapsed = end_time - start_time
    puts
    return "#{elapsed} seconds elapsed for #{description}"
  end
end

benchmarker = Benchmarker.new
puts( benchmarker.run "sleeping random amount of time" do
    5.times do
      print "."
      sleep(rand(0.1..1.0))
    end
  end
)

it runs without error.

Since you aren't explicit with the parenthesis, the interpreter probably assumes this:

 puts( benchmarker.run "sleeping random amount of time" ) do

which gives the same error since the block is now passed to "puts" and not "benchmarker.run"