ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: manga.osyo@gmail.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:95696] [Ruby master Feature#16293] Numbered parameter confirmation in Ruby 2.7
Date: Tue, 05 Nov 2019 12:14:37 +0000 (UTC)	[thread overview]
Message-ID: <redmine.issue-16293.20191105121436.505986941c9c6cce@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-16293.20191105121436@ruby-lang.org

Issue #16293 has been reported by osyo (manga osyo).

----------------------------------------
Feature #16293: Numbered parameter confirmation in Ruby 2.7
https://bugs.ruby-lang.org/issues/16293

* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
## Overview

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

* No warning -> No error in the future
* Warning -> Deprecated syntax
* Error -> Error in 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"
```


## [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


## Current behavior

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

```ruby
def _1
  :method
end

# 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

# 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

# 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" in logs
x = _1
p x
# => :method

# Warning
p eval("_1")
```

```ruby
def _1
  :method
end

# Warning
# "`1.times{|i| _0 }` → force warning on Ruby 2.7 and syntax error on Ruby 3." in logs
p proc { |i| _1 }.call 42
```

```ruby
proc {
  # 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 parameter
  _1 = 42
}

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

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

```ruby
_1 = :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 _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
# 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
  # Error: numbered parameter is already used in
  #        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
# => 42
```

```ruby
# Example 5-8
_1 = :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
```

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

```ruby
# 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 `_1` in binding.irb

```ruby
# 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 :)




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

       reply	other threads:[~2019-11-05 12:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-16293.20191105121436@ruby-lang.org>
2019-11-05 12:14 ` manga.osyo [this message]
2019-11-05 12:56 ` [ruby-core:95698] [Ruby master Feature#16293] Numbered parameter confirmation in Ruby 2.7 hsbt
2019-11-05 13:05 ` [ruby-core:95700] " mame
2019-11-05 16:18 ` [ruby-core:95703] " shevegen
2019-11-06  0:58 ` [ruby-core:95716] " manga.osyo
2019-11-06  3:45 ` [ruby-core:95718] [Ruby master Bug#16293] " nobu

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.issue-16293.20191105121436.505986941c9c6cce@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).