Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

It's common pattern when you need to assign a variable inside a block

def query(sql)
  logger.debug "Db: Executing query #{sql}"
  result = nil
  ts = Benchmark.realtime do
    result = @db.exec sql
  logger.debug "Db: Query completed in #{ts}"

Is there a more elegant way to rewrite this snippet?

share|improve this question

1 Answer 1

I am afraid your code cannot be simplified further due to the imperative nature of Benchmark.realtime (it would have been better if it also returned the result of the block). Anyway, I think the best solution is to abstract it and write a wrapper method. For example:

def benchmark(msg)
  result = nil
  ts = Benchmark.realtime(&block) { result = yield }
  logger.debug("Completed in #{ts} seconds")

def query(sql)
  benchmark("DB: Executing query #{sql}") do

Now, if your question was on a more generic plane, let's say, that you have lots of methods that work like realtime which force you write a lot of boilerplate, I'd propose this generic Object#capture wrapper:

class Object
  def capture(method, *args)
    result2 = nil
    result1 = send(method, *args) { |*bargs| result2 = yield(*bargs) }
    [result1, result2]

realtime_output, block_output = Benchmark.capture(:realtime) do
  "my output"
end #=> [7.263e-06, "my output"]
share|improve this answer
Yeah, I was asking about the generic pattern, the Benchmark.realtime is of course wrapped –  synapse Oct 12 '12 at 13:39
@synapse: I updated the answer, see the second snippet. –  tokland Oct 17 '12 at 14:37

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.