Issue #15192 has been updated by shevegen (Robert A. Heiler).


I personally tend to use (slower) setter-methods rather than initialization within
initialize() itself. Normally only for somewhat larger classes though; for small
classes that do not do much, I often don't bother writing setter methods.

So:

    def initialize(*i)
      reset # <- a method to setup the default state for the objects
      set_commandline_arguments(i) # <- and often keeping track of the commandline arguments passed in via ARGV
      # continue with the assignments via method calls, often in a method called run() that I like to use and call here
    end

Then again I don't think that my ruby code/style is very commonly used either. :)

I understand the shortcut idea behind the proposal, e. g. to get rid of some lines
of code. Personally I have no strong opinion either way since I can understand both
arguments but I think that aside from what shyouhei wrote, matz is also not too fond
of the syntax. In the discussion in the other thread he did not like the:

    def initialize(@foo, @bar)

notation. So I think the additional problem here is clarity of intent and consistency
through idiomatic ruby. People will also of course make use of it a lot and in this
case I am not entirely sure whether that change in particular would be very good,
just syntax-wise. (I also tend to watch crystal, which uses a syntax similar to this,
but crystal also diverged in some strange ways, in my opinion, syntax-wise - e. g
"abstract" classes or macros, which I find very strange.)

- You (or others) could try to re-evaluate the proposals at some later time in the
future since sometimes other parts of ruby or the usage may change (for example, see
the change that allows unicode used as a constant/name of classes, which was not 
possible before not that long ago).


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

* Author: jjyr (Jinyang Jiang)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
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>