Issue #15192 has been updated by austin (Austin Ziegler).


Dan0042 (Daniel DeLorme) wrote in #note-19:
> The syntax `def name(external_name: default_value => internal_name)` has been suggested twice independently (#16460, #18402) so I think that would be fairly intuitive to any rubyist. And if instance variables were allowed as the internal_name, I think this would be a great way to solve this very-often-requested feature.
> 
> Like this:
> ```ruby
>       def initialize(private_key:          => @private_key,
>                      protocol_manage:      => @protocol_manage,
>                      bootstrap_nodes: []   => @bootstrap_nodes,
>                      node_name: 'Ciri'     => @node_name,
>                      tcp_host: '127.0.0.1' => @tcp_host,
>                      tcp_port: 33033       => @tcp_port)
>         server_node_id = NodeID.new(@private_key)
>         caps = [Cap.new(name: 'eth', version: 63)]
>         @handshake = ProtocolHandshake.new(version: BASE_PROTOCOL_VERSION, name: @node_name, id: server_node_id.id, caps: caps)
>         @dial = Dial.new(bootstrap_nodes: bootstrap_nodes, private_key: private_key, handshake: @handshake)
>         @network_state = NetworkState.new(protocol_manage)
>         @dial_scheduler = DialScheduler.new(@network_state, @dial)
>       end
> ```

I would personally prefer `as` over` =>` for this, as it doesn¡Çt _increase_ the number of ways that `=>` gets used in Ruby. Like it or not, Ruby has a reputation for being _almost_ as full of line-noise as Perl, and this pushes things in the wrong direction.

```ruby
 def initialize(private_key: as @private_key, for: 'Ciri' as node_name)
end
```

----------------------------------------
Feature #15192: Introduce a new "shortcut assigning" syntax to convenient setup instance variables
https://bugs.ruby-lang.org/issues/15192#change-95312

* Author: jjyr (Jinyang Jiang)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Motivation:

Introduce a new syntax for convenient setup instance variables for objects.

The problem:

Currently, setup instance variables in Ruby is too verbose. 
Basically, we need to write the meaningless assigning code again and again to assign variables

``` ruby
class Person
  def initialize(name:, age:, gender:, country:)
    @name = name
    @age = age
    @gender = gender
    @country = country
  end
end


# we can use Struct to avoiding this

Person = Struct.new(:name, :age, :gender, :country, keyword_init: true)

# let's see a real-world case, which can't use Struct to describe an initializing process, from https://github.com/ciri-ethereum/ciri/blob/748985ccf7a620a2e480706a5a6b38f56409d487/lib/ciri/devp2p/server.rb#L54
# Because we want to do something more than just assigning instance variables

class Server
      def initialize(private_key:, protocol_manage:, bootstrap_nodes: [],
                     node_name: 'Ciri', tcp_host: '127.0.0.1', tcp_port: 33033)
        @private_key = private_key
        @node_name = node_name
        @bootstrap_nodes = bootstrap_nodes
        @protocol_manage = protocol_manage
        server_node_id = NodeID.new(@private_key)
        caps = [Cap.new(name: 'eth', version: 63)]
        @handshake = ProtocolHandshake.new(version: BASE_PROTOCOL_VERSION, name: @node_name, id: server_node_id.id, caps: caps)
        @tcp_host = tcp_host
        @tcp_port = tcp_port
        @dial = Dial.new(bootstrap_nodes: bootstrap_nodes, private_key: private_key, handshake: @handshake)
        @network_state = NetworkState.new(protocol_manage)
        @dial_scheduler = DialScheduler.new(@network_state, @dial)
      end
end


# Introduce a new "shortcut assigning" syntax for convenient setup

class Person
  # use @ prefix to describe instance variables.
  def initialize(@name:, @age:, @gender:, @country:)
  end

  # equal to
  def initialize2(name:, age:, gender:, country:)
    @name = name
    @age = age
    @gender = gender
    @country = country
  end

  # it should also work on position style arguments
  def initialize2(@name, @age, @gender, @country)
  end
end

# Our real-world case can be rewritten as below
class Server
      def initialize(@private_key:, @protocol_manage:, @bootstrap_nodes: [],
                     @node_name: 'Ciri', @tcp_host: '127.0.0.1', @tcp_port: 33033)
        server_node_id = NodeID.new(@private_key)
        caps = [Cap.new(name: 'eth', version: 63)]
        @handshake = ProtocolHandshake.new(version: BASE_PROTOCOL_VERSION, name: @node_name, id: server_node_id.id, caps: caps)
        @dial = Dial.new(bootstrap_nodes: @bootstrap_nodes, private_key: @private_key, handshake: @handshake)
        @network_state = NetworkState.new(@protocol_manage)
        @dial_scheduler = DialScheduler.new(@network_state, @dial)
      end
end

# consider to keep consistency, this "shortcut assigning" syntax should work for non-initialize methods
class Foo
  def bar(@still_works)
    p @still_works
  end
end
```



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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>