Skip to content

Multiline blocks sometimes use braces, sometimes do/end #379

Closed
@etiennebarrie

Description

@etiennebarrie

This shows the issue with fixtures:

diff --git i/test/fixtures/lambda.rb w/test/fixtures/lambda.rb
index 5dba3be..079c082 100644
--- i/test/fixtures/lambda.rb
+++ w/test/fixtures/lambda.rb
@@ -80,3 +80,83 @@
 -> do # comment1
   # comment2
 end
+% # multiline lambda
+-> {
+  multi
+  line
+}
+-
+-> do
+  multi
+  line
+end
+% # multiline lambda inside a method
+def foo
+  -> {
+    multi
+    line
+  }
+end
+-
+def foo
+  -> do
+    multi
+    line
+  end
+end
+% # nested multiline lambda
+-> {
+  -> {
+    multi
+    line
+  }
+}
+-
+-> do
+  -> do
+    multi
+    line
+  end
+end
+% # multiline lambda in a method_add_block
+method_add_block {
+  -> {
+    multi
+    line
+  }
+}
+-
+method_add_block do
+  -> do
+    multi
+    line
+  end
+end
+% # multiline lambda in a method_add_block with arguments
+method_add_block("arg") {
+  -> {
+    multi
+    line
+  }
+}
+-
+method_add_block("arg") do
+  -> do
+    multi
+    line
+  end
+end
+% # multiline lamda in a command
+command "arg" do
+  -> {
+    multi
+    line
+  }
+end
+-
+command "arg" do
+  -> do
+    multi
+    line
+  end
+end
  • The first case shows that multiline lambdas get formatted with do/end
  • The second case shows that multiline lambdas get formatted with do/end inside methods
  • The third case shows that multiline lambdas get formatted with do/end when nested
  • The fourth case shows that multiline lambdas get formatted with do/end when passed as a block in a method call without arguments (parsed as a method_add_block)
  • The fifth case shows that multiline lambdas get formatted with do/end when passed as a block in a method call with arguments but with parentheses (parsed as a method_add_block)
  • The sixth case is failing, shows that multiline lambdas get formatted with braces when passed as a block in a method call with arguments but no parentheses (which is parsed as a command)

Additionally, Rubocop is fine with braces for multiline lambdas because method calls to lambda (including stabby lambdas), proc and it are special-cased: https://github.com/rubocop/rubocop/blob/1884a46d9284b47a07763e2506276662c7c1ae6e/config/default.yml#L3212-L3214

If we remove that special handling, Rubocop will always enforce using do/end for multiline blocks, but stree write will force braces, when called in a method call with arguments but no parentheses, typically in tests in Rails with ActiveSupport::Testing::Declarative:

class SomeTest < ActiveSupport::TestCase
  test "something" do
    _ = -> do
      multi
      line
    end
  end
end

That makes rubocop and stree incompatible for that rule. Once the formatting is fixed to always generate do/end for multiline lambdas, we could add this to config/rubocop.yml to make them compatible:

Style/BlockDelimiters:
  AllowedMethods: []

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions