`(a || = []) << 1` versus` (i || = 0) + = 1`

Although I have already written Ruby, I am always looking for ways to improve my style.

I'm used to a particularly short, concise method of instantiating + adding to an array:

 ruby-1.9.3-p194 :001 > (a ||= []) << 1 => [1] 

This particular syntax seems only valid when used in conjunction with arrays, since my attempts to do this with other types return syntax errors.

 ruby-1.9.3-p194 :002 > (i ||= 0) += 1 SyntaxError: (irb):2: syntax error, unexpected tOP_ASGN, expecting $end (i ||= 0) += 1 ^ from /usr/local/rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>' 

And also with the lines, although I pretty much expected that this would not work given the previous experiment.

 ruby-1.9.3-p194 :003 > (s ||= '') += 'TEST' SyntaxError: (irb):3: syntax error, unexpected tOP_ASGN, expecting $end (s ||= '') += 'TEST' ^ from /usr/local/rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>' 

What distinguishes an array from other types here when this syntax form is used?

+4
source share
3 answers

In Ruby, as in most other languages, abbreviated assignments are just syntactic sugar for the extended form, i.e.

 a += b 

- syntactic sugar for

 a = a + b 

So,

 (i ||= 0) += 1 

- syntactic sugar for

 (i ||= 0) = (i ||= 0) + 1 

which is simply illegal.

This has nothing to do with arrays, as you can see here:

 (s ||= '') << 'TEST' # works (a ||= []) += [1] # doesn't work 
+5
source

The left side should be variable. What about:

 i = (i || 0) + 1 

or

 i = i ? i + 1 : 1 
0
source

You can use these protected instructions for anything that provides an operation that will change the state of a variable, for example. concat for String, <for array, etc.

 1.9.2p290 :111 > s = nil => nil 1.9.2p290 :112 > (s ||= '').concat 'test' => "test" 1.9.2p290 :113 > (s ||= '').concat 'test' => "testtest" 

For some types, such as FixNum, you really don't have an option, since you cannot change state without assignment, so the closest we could get is succ, but as you can see, it does not update the stored value

 1.9.2p290 :130 > i = nil => nil 1.9.2p290 :131 > (i || 0).succ => 1 1.9.2p290 :132 > (i || 0).succ => 1 

For these types, I recommend the Jรถrg W Mittag sentence i = (i || 0) + 1 , since it is clean enough and displays it well.

 1.9.2p290 :134 > i = nil => nil 1.9.2p290 :135 > i = (i || 0) + 1 => 1 1.9.2p290 :136 > i = (i || 0) + 1 => 2 
0
source

Source: https://habr.com/ru/post/1439606/


All Articles