I am writing a gem where I would like to implement a conditional assignment in a C extension.
The idea is provide assignment for logical defined-or. This would only assign if the variable is nil. For example...
var = false
var //= 42 # var is false
var = nil
var //= 23 # var is 23
I found in the ruby/ruby repository the definition of abbreviated assignment:
There are also ||= and &&=. The former makes an assignment if
the value was nil or false while the latter makes an assignment
if the value was not nil or false.
I did not manage to find a reference in the source code. (As referred in the comments below ||= is not an operator but just syntax sugar)
I tried to look on apidock.com the definition of some bang methods: e.g. Array#map!:
static VALUE
rb_ary_collect_bang(VALUE ary)
{
long i;
RETURN_ENUMERATOR(ary, 0, 0);
rb_ary_modify(ary);
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_ary_store(ary, i, rb_yield(RARRAY_PTR(ary)[i]));
}
return ary;
}
I managed to follow the references to rb_ary_modify and rb_ary_store in array.c.
Would you know how to implement a mutating method such as:
require 'logic_or'
# Current behaviour
nil.lor('a') # => "a"
false.lor('a') # => false
a = nil # => nil
a.lor('a') # => "a"
a # => nil
# Expected behaviour
a = nil # => nil
a.lor!('a') # => "a"
a # => "a"
Update
As pointed out in comments, the previous title (How is Double pipe or equals (||=) implemented in ruby?) was not coherent with the content of the question