Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Ruby have something similar to .=, like +=?

Tags:

ruby

Since one can do:

a += 1

I was thinking whether one can also do something similar to:

a .= 1

The use case would be, for example, with ActiveRecord:

query = Model
query .= where(name: 'John') # instead of query = query.where(name: 'John')

Is this possible somehow?

like image 973
linkyndy Avatar asked Dec 14 '22 23:12

linkyndy


2 Answers

Nope, ruby does not have anything like this. Only certain "compound operators" are allowed by Ruby syntax and this operator is not among them.

However, there might be workarounds under specific circumstances (not this one, though). If, say, you had an array, then instead of

ary = ary.select { ... } if foo
ary = ary.select { ... } if bar
ary = ary.compact

you'd be able to do

ary.select! { ... } if foo
ary.select! { ... } if bar
ary.compact!

(this can have unintended consequences, yes, because in-place mutation is dangerous in general. But in some cases it is desirable. Don't do it to shorten your code.)

like image 116
Sergio Tulentsev Avatar answered Dec 30 '22 21:12

Sergio Tulentsev


Ruby is able to detect line continuations automatically:

query = Model
  .where(name: 'John')
  .select(:first_name)

This is equivalent to this (with the dots at the end):

query = Model.
  where(name: 'John').
  select(:first_name)

Note that due to the way lines are evaluated in IRB, only the second syntax (with the dots at the end of the line) works as intended there. With the first example, IRB would evaluate the line as soon as it sees the newline. In a Ruby script, both options work quite well.

There apply different style considerations here, with people having different opinions on which one is best.

Generally, this approach requires that the combined line is syntactically equivalent to a single line. You can't use inline conditions that way. This would thus be invalid syntax:

query = Model
  .where(name: 'John') if some_condition
  .select(:first_name)

If you require these conditions, it is just fine to assign intermediate results to a local variable as shown by Sergio Tulentsev in his answer. You'll often see this and it is not a code smell at all.

like image 40
Holger Just Avatar answered Dec 30 '22 22:12

Holger Just