Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does "(1..4).inject(&:+)" work in Ruby

Tags:

ruby

I find this code in Ruby to be pretty intriguing

(1..4).inject(&:+)

Ok, I know what inject does, and I know this code is basically equivalent to

(1..4).inject(0) {|a,n| a + n}

but how exactly does it work?

Why &:+ is the same as writing the block {|a,n| a + n}?

Why it doesn't need an initial value? I'm ok with the inicial value being 0, but (1..4).inject(&:*) also works, and there the initial value must be 1...

like image 326
Marcos Crispino Avatar asked Feb 15 '11 11:02

Marcos Crispino


People also ask

What are the execution paths of the @Inject annotation?

The @Inject annotation belongs to the JSR-330 annotations collection. This annotation has the following execution paths, listed by precedence: These execution paths are applicable to both setter and field injection. In order to access the @Inject annotation, the javax.inject library has to be declared as a Gradle or Maven dependency.

What is SQL injection?

SQL injection is the placement of malicious code in SQL statements, via web page input. SQL injection usually occurs when you ask a user for input, like their username/userid, and instead of a name/id, the user gives you an SQL statement that you will unknowingly run on your database.

What is setter-based injection for the @AutoWired annotation?

Setter-based injection for the @Autowired annotation is similar to the approach demonstrated for the @Resource setter-based injection. Instead of annotating the reference variable with the @Inject annotation, we annotate the corresponding setter.

What is the difference between @resource and @inject?

Unlike the @Resource annotation, which resolves dependencies by name first, the default behavior of the @Inject annotation is to resolve dependencies by type. This means that even if the class reference variable name differs from the bean name, the dependency will still be resolved, provided that the bean is defined in the application context.


1 Answers

From Ruby documentation:

If you specify a symbol instead, then each element in the collection will be passed to the named method of memo

So, specifying a symbol is equivalent to passing the following block: {|memo, a| memo.send(sym, a)}

If you do not explicitly specify an initial value for memo, then uses the first element of collection is used as the initial value of memo.

So, there is no magic, Ruby simply takes the first element as the initial value and starts injecting from the second element. You can check it by writing [].inject(:+): it returns nil as opposed to [].inject(0, :+) which returns 0.

Edit: I didn't notice the ampersand. You don't need it, inject will work with a symbol. But if you do write it, the symbol is converted to block, it can be useful with other methods

like image 60
adamax Avatar answered Sep 19 '22 15:09

adamax