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


> marcandre wrote

> I feel that no Rubyist would have trouble learning what def
> initialize(@something, @some_option: nil) would mean; it would
> take about 5 seconds.

I think this is a bit difficult to say, because we can always reason that one small feature that
is added, is just one more tiny little baby step.

But say that you combine lots of baby steps ... all very simple on their own, but together they
add to the complexity or spaghetti design of a language. Like perhaps PHP. 

In Ruby we can also omit () in method definitions like:

    def initialize @a, @b: nil, @c: { cat: :tom }

I am not sure if this is an improvement. To me it does not seem very pretty. Of course I am biased since
I also prefer () in method definitions if they have arguments; although I think it is fine that ruby does
not mind omitting the (). For my brain, I like the () for visual separation. I am not sure I like the @foo
syntax that much on the left hand side. What about syntax like @a = @b? I mean, I assume we assign the
value of @b towards @a ... but ideally I'd prefer to not want to see syntax like that in method definitions;
or having to look closely for : { and @. May be a matter of personal preference too.

Once added, it would also be harder to remove the syntax again, in the sense of people who may like
syntax (like @@ class variables) so I am not entirely sure if it's a great idea. But I don't want to
be too discouraging since it is mostly just a difference of opinions.

Before I write too much, I'll finish by saying that I personally am not that fully convinced that it is
such a good idea to have the proposed feature associated with that particular syntax, even though it is
repeated every now and then (but so were ideas such as removing Symbols; I think jeremy evans wrote good
comments about that other situation). I am also not that convinced that a different syntax will be of
more help, either. Perhaps I am becoming more conservative as I become older. (One problem I see with
a longer syntax is that some of the advantage is lost by short-cutting assignment.)

On a side note, since crystal has that syntax and functionality, people could actually try out crystal and
see how that goes in regards to the "shortcut assignment" after a few months. :) (I mean really mostly
unbiased people here, though ideally those who already know ruby, even though that leads to some bias; and
can then compare to crystal, syntax-wise. Personally I feel that the ruby syntax is better than crystal's
syntax, due to various reason, but I don't want to digress here towards another programming language too
much.)

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

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