My background is in PHP and C#, but I’d really like to learn RoR. To that end, I’ve started reading the official documentation. I have some questions about some code examples.
The first is with iterators:
class Array
def inject(n)
each { |value| n = yield(n, value) }
n
end
def sum
inject(0) { |n, value| n + value }
end
def product
inject(1) { |n, value| n * value }
end
end
I understand that yield means “execute the associated block here.” What’s throwing me is the |value| n = part of the each. The other blocks make more sense to me as they seem to mimic C# style lambdas:
public int sum(int n, int value)
{
return Inject((n, value) => n + value);
}
But the first example is confusing to me.
The other is with symbols. When would I want to use them? And why can’t I do something like:
class Example
attr_reader @member
# more code
end
In the
injectorreducemethod,nrepresents an accumulated value; this means the result of every iteration is accumulated in thenvariable. This could be, as is in your example, the sum or product of the elements in the array.yieldreturns the result of the block, which is stored innand used in the next iterations. This is what makes the result “cumulative.”Also, to compute the sum you could also have written
a.reduce :+. This works for any binary operation. If your method is namedsymbol, writinga.reduce :symbolis the same as writinga.reduce { |n, v| n.symbol v }.attrand company are actually methods. Under the hood, they dynamically define the methods for you. It uses the symbol you passed to work out the names of the instance variable and the methods.:memberresults in the@memberinstance variable and thememberandmember =methods.The reason you can’t write
attr_reader @memberis because@memberisn’t an object in itself, nor can it be converted to a symbol; it actually tells ruby to fetch the value of the instance variable@memberof theselfobject, which, at class scope, is the class itself.To illustrate:
Remember that accessing unset instance variables yields
nil, and since theattrmethod family accepts only symbols, you get:TypeError: nil is not a symbol.Regarding Symbol usage, you can sort of use them like strings. They make excellent hash keys because equal symbols always refer to the same object, unlike strings.
They’re also commonly used to refer to method names, and can actually be converted to
Procs, which can be passed to methods. This is what allows us to write things likearray.map &:to_s.Check out this article for more interpretations of the symbol.