Project

General

Profile

Bug #16293

Updated by osyo (manga osyo) about 5 years ago

 
 ## Overview 

 I want to make a final check on the behavior of Numbered parameter( No warning or Warning or Error). Error. 

 * No warning -> No error in the future 
 There is a difference * Warning -> Deprecated syntax 
 * Error -> Error in [DevelopersMeeting20190829Japan logs](https://docs.google.com/document/d/1XypDO1crRV9uNg1_ajxkljVdN8Vdyl5hnz462bDQw34/edit) and behavior. Ruby 2.7 


 ## Ruby version 

 ```ruby 
 p RUBY_VERSION 
 # => "2.7.0" 
 p RUBY_DESCRIPTION 
 # => "ruby 2.7.0dev (2019-11-02T06:32:49Z trunk 772b0613c5) [x86_64-linux]" 
 p RUBY_RELEASE_DATE 
 # => "2019-11-02" 
 p RUBY_REVISION 
 # => "772b0613c583773cd2eda23bce8275926a351e79" 
 ``` 


 ## [DevelopersMeeting20190829Japan logs](https://docs.google.com/document/d/1XypDO1crRV9uNg1_ajxkljVdN8Vdyl5hnz462bDQw34/edit) [Log in DevelopersMeeting20190829Japan](https://docs.google.com/document/d/1XypDO1crRV9uNg1_ajxkljVdN8Vdyl5hnz462bDQw34/edit) 

 * local variables (parameters and assigned variable) → force warning (Don’t use) on Ruby 2.7 and syntax error on Ruby 3. 
 * method invocation 
   * vcall: `x = _0 # expect _0()` outside block. → force warning on Ruby 2.7 and syntax error on Ruby 3. 
   * vcall: `1.times{ _0 }` → block parameter (incompatibility) 
   * vcall: `1.times{|i| _0 }` → force warning on Ruby 2.7 and syntax error on Ruby 3. 
 * method invocation (`x = _0(), x = foo._0`) → no warning 
 * method name (`def _0(); end`) → no warning 


 ## Proposal Current behavior 

 ```ruby 
 # No warning 
 # Defined parameter name `_1` 
 def _1; hgoe(_1) 
 end 
 ``` 

 ```ruby 
 def _1 
   :method 
 end 

 # expected: warning: `_1' is used as No warning 
 # Call to method `_1` 
 x = _1 
 p x 
 # => :method 

 # Error: numbered parameter outside block (SyntaxError) 
 p eval("_1") 
 ``` 

 ```ruby 
 def _1 
   :method 
 end 

 # actual: Error: ordinary parameter is defined 
 p proc { |i| _1 }.call 42 
 ``` 

 ```ruby 
 proc { 
   # Warning 
   _1 = 42 
 } 

 proc { 
   _1 
   # No warning 
   # Defined local variable 
   _1 = 42 
 } 
 ``` 

 ```ruby 
 def _1 
   :method 
 end 

 # reason: Because No warning 
 p _1 

 # Error: numbered parameter outside block (SyntaxError) 
 p eval("_1") 
 ``` 

 ## Proposal 

 * When deprecated in the future, it is necessary to issue a Warning 
 * Considering compatibility, make it Warning instead of Error 

 ```ruby 
 def _1 
   :method 
 end 

 # Warning 
 # "`x = _0 # expect _0()` outside block. → force warning on Ruby 2.7 and syntax error on Ruby 3" is written in the log logs 
 x = _1 

 # expected: warning: `_1' is used as numbered parameter 
 #             and call to _1() p x 
 # actual: Error: numbered parameter outside block (SyntaxError) 
 => :method 

 # reason: Because hoge() method is called with `eval("hoge")` Warning 
 p eval("_1") 
 ``` 

 ```ruby 
 def _1; _1 
   :method 
 end 

 # expected: warning: `_1' is used as numbered parameter Warning 
 #             and call to _1() 
 # actual: Error: ordinary parameter is defined 
 # reason: Because "`1.times{|i| _0 }` → force warning on Ruby 2.7 and syntax error on Ruby 3." is written in the log logs 
 p proc { |i| _1 }.call 42 
 ``` 

 ```ruby 
 proc { 
   # expected: warning: Warning 
   _1 = 42 
 } 

 proc { 
   _1 
   # Warning 
   _1 = 42 
 } 
 ``` 

 ```ruby 
 # Warning 
 # Since local variables are also warnings, formal parameters are also warnings 
 def hgoe(_1) 
 end 

 # NOTE 
 # `eval("_1")` refers to a dummy argument 
 def hoge(_1) 
   p proc { 
     _1 
     eval("_1") 
   }.call 42 
 end 
 hoge :argument 
 # => :argument 
 ``` 

 ## Other behavior 

 * Is there any other syntax to change `No warning` `Warning` `Error` ? 

 ### Example 1. Defined local variable name `_1` 

 ```ruby 
 # Example 1-1 
 # Warning : defined local variable 
 _1 = 42 
 ``` 

 ```ruby 
 # Example 1-2 
 # No warning : defined method name 
 def _1 
   42 
 end 
 ``` 

 ```ruby 
 # Example 1-3 
 # No warning : defined parameter name 
 def hgoe(_1) 
 end 
 ``` 

 ```ruby 
 # Example 1-4 
 # In block 
 proc { 
   # Warning: `_1' is used as numbered Numbered parameter 
   _1 = 42 
 } 

 # actual: Example 1-5 
 # In block and used Numbered parameter 
 proc { 
   _1 
   # No warning 
   _1 = 42 
 # reason: Because define } 
 ``` 

 ### Example 2. Refer to local variable `_1` in block 

 ```ruby 
 _1 is = :local_variable 

 # Example 2-1 
 # No warning 
 x = _1 
 p x 
 # => :local_variable 

 # Example 2-2 
 # No warning 
 p proc { |i| _1 }.call 3 
 # => :local_variable 

 # Example 2-3 
 # No warning 
 p proc { _1 }.call 3 
 # => :local_variable 

 # Example 2-4 
 p proc { 
   _1 
   proc { 
     # No warning 
     _1 
   }.call 
 }.call 42 
 # => :local_variable 
 ``` 

 ### Example 3. Refer to method `_1` in block 

 ```ruby 
 def hgoe(_1) _1(a = nil) 
   :"method#{a}" 
 end 

 # Example 3-1 
 # No warning 
 x = _1 
 p x 
 # => :method 

 # Example 3-2 
 # No warning 
 x = _1 42 
 p x 
 # => :method42 

 # Example 3-3 
 # No warning 
 x = _1() 
 p x 
 # => :method 

 # Example 3-4 
 # Error 
 p proc { |i| _1 }.call 42 

 # Example 3-5 
 # No warning 
 p proc { |i| _1() }.call 42 
 # => :method 

 # Example 3-6 
 # No warning 
 p proc { |i| _1 i }.call 42 
 # => :method42 

 # Example 3-7 
 # No warning 
 p proc { |i| self._1 }.call 42 
 # => :method 

 # Example 3-8 
 # No warning 
 p proc { _1 }.call 42 
 # => 42 

 # Example 3-9 
 # No warning 
 p proc { _1 _2 }.call 42, 3 
 # => method3 

 # Example 3-10 
 # No warning 
 p proc { _1() }.call 42 
 # => :method 

 # Example 3-11 
 # No warning 
 p proc { self._1 }.call 42 
 # => :method 

 ``` 


 ### Example 4. Defined local variable `_1` and method `_1` 

 ```ruby 
 def _1(a = nil) 
   :"method#{a}" 
 end 

 _1 = :local_variable 

 # Example 4-1 
 # No warning 
 p proc { |i| _1 }.call 3 
 # => :local_variable 

 # Example 4-2 
 # No warning 
 p proc { |i| _1() }.call 3 
 # => :method 

 # Example 4-3 
 # No warning 
 p proc { |i| _1 42 }.call 3 
 # => :method42 

 # Example 4-4 
 # No warning 
 p proc { _1 }.call 3 
 # => :local_variable 

 # Example 4-5 
 # No warning 
 p proc { _1() }.call 3 
 # => :method 

 # Example 4-6 
 # No warning 
 p proc { _1 42 }.call 3 
 # => :method42 
 ``` 

 ### Example 5. Used `eval("_1")` 

 * `eval ("_1")` refers to local variables in preference 
   * The same goes for `binding.local_variable_get(:_1)` 
 * If local variable `_1` becomes Error, solve it? 
 * `eval("@1")` is Syntax Error 

 ```ruby 
 # Warning 
   Example 5-1 
 # Error: numbered parameter outside block (SyntaxError) 
 p proc { eval("_1") }.call 42 
 ``` 

 ```ruby 
 # Example 5-2 
 # No warning 
 p proc { _1; eval("_1") }.call 42 
 # => 42 
 ``` 

 ```ruby 
 _1 = :local_variable 

 # Example 5-3 
 # No warning 
 p eval("_1") 
 # => :local_variable 

 # Example 5-4 
 # No warning 
 p proc { eval("_1") }.call 42 
 } # => :local_variable 

 # Example 5-5 
 # No warning 
 p proc { _1; eval("_1") }.call 42 
 # => :local_variable 
 ``` 

 ```ruby 
 # Example 5-6 
 p proc { 
   _1 
   # expected: warning: `_1' Error: numbered parameter is already used as numbered parameter in 
   # actual:          outer block here 
   proc { _1 }.call 3 
 }.call 42 
 ``` 

 ```ruby 
 # Example 5-7 
 p proc { 
   _1 
   proc { 
     # No warning 
     eval("_1") 
   }.call 3 
 }.call 42 
 # reason: Because define local variable => 42 
 ``` 

 ```ruby 
 # Example 5-8 
 _1 is = :local_variable 
 p proc { 
   _1 
   proc { 
     # No warning 
     eval("_1") 
   }.call 3 
 }.call 42 
 # => :local_variable 
 ``` 

 ```ruby 
 def _1 
   :method 
 end 

 # Example 5-9 
 # No warning 
 p _1 
 # => :method 

 # Example 5-10 
 # Error: numbered parameter outside block (SyntaxError) 
 p eval("_1") 

 # Example 5-11 
 # No warning 
 p eval("_1()") 
 # => :method 

 # Example 5-12 
 # Error: numbered parameter outside block (SyntaxError) 
 p proc { eval("_1") }.call 42 

 # Example 5-13 
 # No warning 
 p proc { _1; eval("_1") }.call 42 
 # => 42 
 ``` 


 ### Example 6. Used default arguments 

 ```ruby 
 # Example 6-1 
 # OK 
 p proc { |_1| 
   -> (a = _1) { a }.call 
 }.call 42 
 } # => 42 
 ``` 

 ## :MEMO: Other behavior ```ruby 
 # Example 6-2 
 # OK 
 _1 = :local_variable 
 p proc { 
   -> (a = _1) { a }.call 
 }.call 42 
 # => :local_variable 
 ``` 

 * Other current behavior : https://gist.github.com/osyo-manga/f332ba1f31dbc3a437acd4d86d7986dc ```ruby 
 * Is there any other syntax # OK 
 def _1 
   :method 
 end 

 p proc { 
   _1 
   eval("_1") 
 }.call 42 
 # => 42 
 ``` 

 ```ruby 
 # Example 6-3 
 # NG 
 p proc { 
   # Error: ordinary parameter is defined 
   -> (a = _1) { a }.call 
 }.call 42 
 ``` 

 ```ruby 
 # Example 6-4 
 # OK 
 p proc { |_1| 
   -> (a = _1) { a }.call 
 }.call 42 
 # => 42 
 ``` 

 ```ruby 
 # Example 6-5 
 # OK 
 _1 = :local_variable 
 p proc { 
   -> (a = _1) { a }.call 
 }.call 42 
 # => :local_variable 
 ``` 

 ```ruby 
 # Example 6-6 
 # NG 
 p proc { 
   # Error: ordinary parameter is defined 
   -> (a = _1) { a }.call 
 }.call 42 
 ``` 


 ### Example 7. Refrer to change `No warning` `Warning` `Error` ? `_1` in binding.irb 

 ```ruby 
 * Considering compatibility, make it Warning instead of Error ? 


 # Example 7-1 
 proc { 
   _1 
   # Referencing _1 returns 42 
   binding.irb 
 }.call 42 
 ``` 

 ```ruby 
 # Example 7-2 
 _1 = :local_variable 
 proc { 
   _1 
   # Referencing _1 returns :local_variable 
   binding.irb 
 }.call 42 
 ``` 

 Are there other edge cases for Numbered parameter? 
 Thank you :) 

 

Back