Issue #13820 has been updated by phluid61 (Matthew Kerwin).


williamn (William Newbery) wrote:
> 
> phluid61 (Matthew Kerwin) wrote:
> > In perl I find `$x // $y` useful vs `$x || $y` because sometimes you want to accept `""` and `0` as values.
>
> But not `false`?
> 

Not in perl ;)

> 
> While `hash.fetch` is nice, I still see `||` used a lot, in places that maybe wont convert so nice. Also it wont short circuit, in the event the default is not trivial (e.g. with say active record stuff, its easy to have something that goes to the DB without really thinking about it).
> 

Yes, short-circuit is handy.  It's why I was a proponent of `&.`.  Maybe it's okay to add `//` even if it's only used sometimes.



----------------------------------------
Feature #13820: Add a nill coalescing operator
https://bugs.ruby-lang.org/issues/13820#change-66210

* Author: williamn (William Newbery)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
It would be nice if Ruby had an operator that only considered `nil` as false, like the null coalescing operators or "Logical Defined-Or operator" (Perl) found in some other languages. Ive seen things like `//` and `//=`m `??` and `??=`, or `?:` used for this.

This would work like `||` and `||=` for short circuiting etc. except that only `nil` is considered a false condition.

While Ruby considers only "false" and "nil" as false, with everything else true ("", [], {}, etc.) I still find occasionally people trip up when using logical or, `||` and `||=` when the value may be false.


```ruby
a = 0     || 55 # = 0 Ruby already considers 0, "", etc. as true (oter languages do differ a lot here)
a = 0     ?? 55 # = 0 So no change here
a = nil   || 55 # = 55, nil is false so right side is evaulated.
a = nil   ?? 55 # = 55, again no change
a = false || 55 # = 55, however false is false for logical or
a = false ?? 55 # = false, but its still a non-nil value
```


For example when doing things like:

```ruby
def lazy
  @lazy ||= compute_this
end


def fetch(id, **opts)
  host  = opts[:host] || default_host
  https = opts[:https] || true
  port  = opts[:port] || (https ? 443 : 80)
  ...
```

Normally the intention is to use a default value or compute an action if no value is provided, which if the value may be false then requires special handling, or sometimes is missed and results in a bug.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>