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)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.