PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, November 11, 2022

[FIXED] How to pass a block (which becomes a Proc object) to a ruby method

 November 11, 2022     proc, ruby     No comments   

Issue

I'm reading the Pickaxe book on Ruby and I've come across this example:

class TaxCalculator
  def initialize(name, &block)
    @name, @block = name, block
  end

  def get_tax(amount)
    "#@name on #{amount} = #{@block.call(amount)}"
  end
end

tc = TaxCalculator.new ("Sales tax") {|amt| amt * 0.075 }

tc.get_tax(100) # => "Sales tax on 100 = 7.5"
tc.get_tax(250) # => "Sales tax on 250 = 18.75"

The point of the example is to illustrate that if you prefix the last parameter in a method definition with an ampersand, any associated block is coverted to a Proc object, and that object is assigned to the parameter.

Now, that all makes sense, but I'm stumped on one thing: why do you need to assign name and block to @block in the initialize method? Why do you need name?

To me it seems like this should work:

 def initialize(name, &block)
   @name, @block = block
 end

But, when I try that in irb @block becomes nil and I get an error, NoMethodError (undefined method "call" for nil:NilClass).

I don't understand what name is doing in that @block assignment. It makes sense that you would want to pass "Sales Tax" to @name. But I don't see how "Sales Tax" is being used by the block.


Solution

The assignment syntax has nothing to do with blocks. Instead, what is happening here is called "parallel assignment".

With that, you can assign multiple variables on the left from multiple values on the right with one atomic operation. From your example, this statement

@name, @block = name, block

is equivalent to

@name = name
@block = block

In this example, this usage is more of a gimmick (which I'd flag in a code-review). However, there are some patterns where parallel assignment is very useful.

The most import one is the ability to switch the values of two variables without requiring an intermediate variable:

a = 1
b = 2
a, b = b, a

Another option is the ability to deconstruct an array into multiple variables. In the following example, the method returns an array whose elements get assigned to the two variables hello and world.

def get_array
  [:hello, :world]
end

hello, world = get_array


Answered By - Holger Just
Answer Checked By - Marie Seifert (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing