Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block arg '&' dose not always follow no whitespace #2414

Conversation

makenowjust
Copy link
Contributor

What no-whitespace check is needed on is only when block arg is passed as first argument and method calling is not wrapped by parentheses, because such a case cannot ditinguish between block arg '&' and binary operator '&'. e.g.

foo 1, & bar # == foo(1, &bar)
foo(& bar)   # == foo(&bar)

foo & bar    # which dose it mean 'foo(&bar)' or '(foo & bar)'?
             # curretly, it parsed to '(foo & bar)'.

You may think this fix makes syntax more complex. Don't worry, plus '+' and minus '-' syntax have same complexity already. e.g.

foo +1  # == foo(+1)
foo + 1 # == (foo + 1)

Current implementation accepts only no-whitespace case, dose not accept following whitespace case. This behavior is different from Ruby, and this change is useful to write some complex expression as block args.

Note: no-whitespace following check is here.

What no-whitespace check is needed on is only when block arg is passed
as first argument and method calling is not wrapped by parentheses,
because such a case cannot ditinguish between block arg '&' and binary
operator '&'. e.g.

    foo 1, & bar # == foo(1, &bar)
    foo(& bar)   # == foo(&bar)

    foo & bar    # which dose it mean 'foo(&bar)' or '(foo & bar)'?
                 # curretly, it parsed to '(foo & bar)'.

You may think this fix makes syntax more complex. Don't worry, plus '+'
and minus '-' syntax have same complexity already. e.g.

    foo +1  # == foo(+1)
    foo + 1 # == (foo + 1)

Current implementation accepts only no-whitespace case, dose not accept
following whitespace case. This behavior is different from Ruby, and
this change is useful to write some complex expression as block args.
@asterite
Copy link
Member

asterite commented Apr 5, 2016

Hi @makenowjust,

Not sure about this change. I know space can make a difference (the +1 case), but I don't see a reason to allow a space before a block argument. The lack of a space between & and the next word makes it super obvious that it's a block argument and it's visually more easy to spot.

Why do you need this?

@makenowjust
Copy link
Contributor Author

I write long method chain with new line, see following:

foo(&
  .it_s(:long)
  .method
  .chain(:foo, :bar))

and, above example can rewrite by using itself for current compiler:

foo(&.itself
  .it_s(:long)
  .method
  .chain(:foo, :bar))

I think such a meaningless method call makes us confused on code reading, so it should be removed.

(Note: this fix cannot change to parse above code because parse_call_block_args dosen't skip newline, however I think this fix is one step to it.)

@asterite
Copy link
Member

@makenowjust You can write it like this:

foo(&.it_s(:long)
     .method
     .chain(:foo, :bar))

I'd like to keep the meaning of & right next to the following expression as meaning "block argument". This is similar to splat *arg and double splat **arg, and it makes code more visually clear.

I don't think this use case justifies this change, as there's a way to write it, and it's maybe not that frequent, so I'll close this.

@asterite asterite closed this May 30, 2016
@makenowjust makenowjust deleted the fix/block-args-ampersand-not-following-no-whitespace-always branch December 6, 2016 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants