ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: alonecomp@gmail.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:71271] [Ruby trunk - Feature #11537] Introduce "Safe navigation operator"
Date: Thu, 29 Oct 2015 19:32:57 +0000	[thread overview]
Message-ID: <redmine.journal-54644.20151029193254.a1e94110d2d6e009@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-11537.20150918092909@ruby-lang.org

Issue #11537 has been updated by Laurentiu Macovei.


The same discussion happens to be on TypeScript and ES6 worlds.
Using .. instead of ?. or .? because it's way more clear when you are using the ternary ? : operator on the same line.

If it's not a conflict in Ruby syntax perhaps worths looking at 

https://esdiscuss.org/topic/existential-operator-null-propagation-operator#content-65
https://github.com/Microsoft/TypeScript/issues/16#issuecomment-152275052

Posting the markdown info from there: 

This would be amazing operator!! Especially for `ES6`/`ES7`/`TypeScript` - and why not `Ruby` ?

```js
var error = a.b.c.d; //this would fail with error if a, b or c are null or undefined.
var current = a && a.b && a.b.c && a.b.c.d; // the current messy way to handle this
var currentBrackets = a && a['b'] && a['b']['c'] && a['b']['c']['d']; //the current messy way to handle this
var typeScript = a?.b?.c?.d; // The typescript way of handling the above mess with no errors
var typeScriptBrackets = a?['b']?['c']?['d']; //The typescript of handling the above mess with no errors
```
However I propose a more clear one - as not to confuse ? from the a ? b : c statements with a?.b statements:

```js
var doubleDots = a..b..c..d; //this would be ideal to understand that you assume that if any of a, b, c is null or undefined the result will be null or undefined.
var doubleDotsWithBrackets = a..['b']..['c']..['d'];
```

For the bracket notation, I recommend two dots instead of a single one as it's consistent with the others when non brackets are used. Hence only the property name is static or dynamic via brackets.

Two dots, means if its null or undefined stop processing further and assume the result of expression is null or undefined. (as d would be null or undefined).

Two dots make it more clear, more visible and more space-wise so you understand what's going on.

This is not messing with numbers too - as is not the same case e.g.

```js
1..toString(); // works returning '1'
var x = {};
x.1 = {y: 'test' }; //fails currently
x[1] = {y: 'test' }; //works currently 
var current = x[1].y; //works
var missing= x[2].y; //throws exception
var assume= x && x[2] && x[2].y; // works but very messy
```

About numbers two options: Your call which one can be adopted, but I recommend first one for compatibility with existing rules!
1. Should fail as it does now (`x.1.y` == `runtime error`)
```js
var err = x..1..y; // should fail as well, since 1 is not a good property name, nor a number to call a method, since it's after x object.
```
2. Should work since it understands that is not a number calling a property from `Number.prototype`
```js
var err = x..1..y; // should work as well, resulting 'test' in this case
var err = x..2..y; // should work as well, resulting undefined in this case
```


With dynamic names:
```js
var correct1 = x..[1]..y; //would work returning 'test'
var correct2 = x..[2]..y; //would work returning undefined;
```

What do you think folks?

P.S. `foo?.bar` and `foo?['bar']` syntax would work too.

However the using both current `?` `:` operator and `?.` might be very confusing on the same line.

e.g. using `?.` and `?['prop']`
```js
var a = { x: { y: 1 } };
var b = condition ? a?.x.?y : a?.y?.z;
var c = condition ? a?['x']?['y'] : a?['y']?['z'];
```
as opposed to double dots `..` and `..['prop']`
```js
var a = { x: { y: 1 } };
var b = condition ? a..x..y : a..y..z;
var c = condition ? a..['x']..['y'] : a..['y']..['z'];
```

##### Which one does look more clear to you?

----------------------------------------
Feature #11537: Introduce "Safe navigation operator"
https://bugs.ruby-lang.org/issues/11537#change-54644

* Author: Hiroshi SHIBATA
* Status: Closed
* Priority: Normal
* Assignee: Yukihiro Matsumoto
----------------------------------------
I sometimes write following code with rails application:

```ruby
u = User.find(id)
if u && u.profile && u.profile.thumbnails && u.profiles.thumbnails.large
  ...
```

or

```ruby
# Use ActiveSupport
if u.try!(:profile).try!(:thumbnails).try!(:large)
 ...
```
I hope to write shortly above code. Groovy has above operator named "Safe navigation operator" with "`?.`" syntax.
Ruby can't use "`?.`" operator.

Can we use "`.?`" syntax. like this:

```ruby
u = User.find(id)
u.?profile.?thumbnails.?large
```

Matz. How do you think about this?




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

  parent reply	other threads:[~2015-10-29 19:05 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-11537.20150918092909@ruby-lang.org>
2015-09-18  9:29 ` [ruby-core:70854] [Ruby trunk - Feature #11537] [Open] Introduce "Safe navigation operator" shibata.hiroshi
2015-09-18  9:31   ` [ruby-core:70855] " P.S.V.R
2015-09-18 14:34 ` [ruby-core:70856] [Ruby trunk - Feature #11537] " rr.rosas
2015-09-19  0:42 ` [ruby-core:70861] " nobu
2015-09-19  4:09 ` [ruby-core:70862] " matthew
2015-09-23 17:04 ` [ruby-core:70892] " rr.rosas
2015-10-07 14:30 ` [ruby-core:71012] " matz
2015-10-07 16:51 ` [ruby-core:71015] " sawadatsuyoshi
2015-10-21  7:45 ` [ruby-core:71129] " matz
2015-10-21  8:05 ` [ruby-core:71130] " matz
2015-10-21 10:21 ` [ruby-core:71132] " rr.rosas
2015-10-21 19:29 ` [ruby-core:71135] " ruby-core
2015-10-21 23:33 ` [ruby-core:71137] " nobu
2015-10-22 16:29 ` [ruby-core:71157] " treznick
2015-10-22 16:34 ` [ruby-core:71158] " ary
2015-10-22 16:45 ` [ruby-core:71160] " merch-redmine
2015-10-22 21:19   ` [ruby-core:71166] " Matthew Kerwin
2015-10-23  3:58 ` [ruby-core:71169] " treznick
2015-10-26  5:10 ` [ruby-core:71182] " transfire
2015-10-26 11:22 ` [ruby-core:71184] " garysweaver
2015-10-26 12:25 ` [ruby-core:71186] " wycats
2015-10-26 13:28 ` [ruby-core:71189] " nobu
2015-10-26 13:58 ` [ruby-core:71190] " rr.rosas
2015-10-27  9:13 ` [ruby-core:71213] " philip.claren
2015-10-27 11:47 ` [ruby-core:71215] " rr.rosas
2015-10-27 12:01 ` [ruby-core:71216] " mame
2015-10-27 12:07 ` [ruby-core:71217] " rr.rosas
2015-10-27 12:24 ` [ruby-core:71218] " mame
2015-10-27 12:31 ` [ruby-core:71219] " rr.rosas
2015-10-27 12:45 ` [ruby-core:71220] " mame
2015-10-27 14:31 ` [ruby-core:71221] " matz
2015-10-29 19:32 ` alonecomp [this message]
2015-10-29 21:00   ` [ruby-core:71273] " Matthew Kerwin
2015-11-04  0:01 ` [ruby-core:71322] " transfire
2015-11-04  0:07 ` [ruby-core:71324] " transfire
2015-11-04  0:32 ` [ruby-core:71325] " nobu
2015-11-04  0:44 ` [ruby-core:71326] " matz
2015-11-05 23:01 ` [ruby-core:71360] " tom.enebo
2015-11-05 23:42   ` [ruby-core:71361] " Eric Wong
2015-11-06  1:25 ` [ruby-core:71363] " matz
2015-11-06  1:50 ` [ruby-core:71364] " tom.enebo
2015-11-06  2:21 ` [ruby-core:71365] " nobu
2015-11-06  4:16 ` [ruby-core:71370] [Ruby trunk - Feature #11537] [Open] " shugo
2015-11-06 18:06 ` [ruby-core:71373] [Ruby trunk - Feature #11537] " rr.rosas
2015-11-07  0:49 ` [ruby-core:71374] " nobu
2015-11-07  2:32 ` [ruby-core:71375] " ko1
2015-11-09 14:39 ` [ruby-core:71417] " tom.enebo
2015-11-13 10:46 ` [ruby-core:71483] " uwe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-54644.20151029193254.a1e94110d2d6e009@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).