X Tutup
The Wayback Machine - https://web.archive.org/web/20201018064055/https://github.com/prettier/plugin-ruby/issues/651
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

Lambda literal arguments invalid after formatting #651

Closed
jbielick opened this issue Oct 12, 2020 · 1 comment
Closed

Lambda literal arguments invalid after formatting #651

jbielick opened this issue Oct 12, 2020 · 1 comment

Comments

@jbielick
Copy link

@jbielick jbielick commented Oct 12, 2020

Documenting this here and will open a PR for it.

Metadata

  • Ruby version: 2.6
  • @prettier/plugin-ruby version: 0.20.1

Input

  scope :sandbox, ->(true_or_false = !Rails.env.production?) { where(sandbox: true_or_false) }

Current output

  scope :sandbox,
        lambda { |true_or_false = !Rails.env.production?|
          where(sandbox: true_or_false)
        }

Expected output

  scope :sandbox,
        ->(true_or_false = !Rails.env.production?) {
          where(sandbox: true_or_false)
        }

Reasoning

The current output is invalid ruby syntax. I did my best to read through the ruby grammar (parse.y) and determine why a unary (!) would be valid in ->(...), but not in do |...| and I was grasping at straws a bit. I'm not experienced enough with the grammar there to determine if there's a bug in the parser and it's picking the wrong matcher for args in do |...| where a unary isn't allowed, but nonetheless it breaks.

Example:

>> ->(active = !dead?) { '' }
=> #<Proc:0x00007f968403ac10@(irb):1 (lambda)>
>> lambda { |active = !dead?| '' }
Traceback (most recent call last):
        3: from /Users/jbielick/.rubies/ruby-2.6.6/bin/irb:23:in `<main>'
        2: from /Users/jbielick/.rubies/ruby-2.6.6/bin/irb:23:in `load'
        1: from /Users/jbielick/.rubies/ruby-2.6.6/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
SyntaxError ((irb):2: syntax error, unexpected '!')
lambda { |active = !dead?| '' }
                   ^
(irb):2: syntax error, unexpected '}', expecting end-of-input
lambda { |active = !dead?| '' }

Without determining exactly what the parsing grammar allow and disallows, I found it difficult to propose a change that would conditionally use -> vs. lambda { when a particular arg pattern was detected. It was my assumption that detection of exceptions where -> must be used was futile. As a result, I think the best course of action is to use -> for everything, since the args patterns it allows are a superset of do |...| (block params) and it is likely unsafe to transform a ->(...) into lambda { |...|.

@jbielick
Copy link
Author

@jbielick jbielick commented Oct 12, 2020

For what it's worth, these were my notes from tracing what grammar might be used for each case:

->(optional = !something?) {}
tLAMBDA: `->`
f_larglist: `(...)`
  f_args: `optional = !something?`
    f_optarg: `f_opt`
      f_opt: `f_arg_asgn '=' arg_value`
        arg_value: `arg`
          arg: `lhs '=' arg_rhs`
            arg_rhs: `arg`
              arg: `primary (almost anything)`
lambda { |optional = !something?| '' }
lambda:
  brace_body: `{ ... }`
    opt_block_param: `none | block_param_def`
      block_param_def: 

        - `'|' opt_bv_decl '|'`
          opt_bv_decl: `bv_decls`
            bv_decls: `bvar | bv_decls ',' bvar`
              bvar: `tIDENTIFIER`

        <!-- matches the above before this? -->

        - `'|' block_param opt_bv_decl '|'`
          block_param: `f_block_optarg`
            f_block_optarg: `f_block_opt`
              f_block_opt: `f_arg_asgn '=' primary_value`
                primary_value: `primary`
                  primary: `(almost anything...)` 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

1 participant
You can’t perform that action at this time.
X Tutup