Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When blocks are more useful than functions (ruby)?

I have two examples that give the same result.

With block:

def self.do_something(object_id)
  self.with_params(object_id) do |params|
    some_stuff(params)
  end
end

def self.with_params(object_id, &block)
  find_object_by_id
  calculate_params_hash
  block.call(params_hash)
end

and with method:

def self.do_something(object_id)
  some_stuff(self.get_params(object_id))
end

def self.get_params(object_id)
  find_object_by_id
  calculate_params_hash
  params_hash
end

The second solution seems more straightforward, but I found some usages of the first one in our application code. My question is: in which situation the first one is recommended? What are the pros and cons of each one?

like image 827
santuxus Avatar asked Mar 15 '12 11:03

santuxus


People also ask

Why we use blocks in Ruby?

A block looks similar to a method in Ruby. Methods consist of a name, but with blocks we don't need to write a name, and always pass to a method call. Blocks are a handy and powerful feature in Ruby, and we can use them anywhere. Blocks are anonymous pieces of code that accept input from arguments and return a value.

What is the difference between a block and method Ruby?

A block is the same thing as a method, but it does not belong to an object. Blocks are called closures in other programming languages. There are some important points about Blocks in Ruby: Block can accept arguments and returns a value.

What are Ruby blocks?

Ruby blocks are little anonymous functions that can be passed into methods. Blocks are enclosed in a do / end statement or between brackets {} , and they can have multiple arguments.

How do you pass blocks in Ruby?

In Ruby, methods can take blocks implicitly and explicitly. Implicit block passing works by calling the yield keyword in a method. The yield keyword is special. It finds and calls a passed block, so you don't have to add the block to the list of arguments the method accepts.


1 Answers

Normally people use blocks when they want to run a piece of code inside of another piece of code. Examples:

DB.with_shard_for_user(user_id) do |db|
  # perform operations on a user's shard

end # shard is reverted back to original value

File.new(filename) do |file|
  # work with file
end # file is closed automatically

User.transaction do
  # run some operations as a single transaction
end

These blocks are closed on their lexical context (they capture variables from where the block is declared, and carry them over to the place when blocks are called).

Schematic structure of a method that accepts a block.

def transaction
  open_transaction # pre- part

  yield if block_given? # run provided code

  commit_transaction # post- part
rescue
  rollback_transaction # handle problems
end

In your first example, use of a block is probably unjustified (IMHO). Too complex for no apparent reason.

like image 177
Sergio Tulentsev Avatar answered Oct 01 '22 09:10

Sergio Tulentsev