From: "austin (Austin Ziegler)" Date: 2021-12-13T19:43:53+00:00 Subject: [ruby-core:106640] [Ruby master Feature#15192] Introduce a new "shortcut assigning" syntax to convenient setup instance variables 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: