ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:94480] [Ruby master Feature#16115] Keyword arguments from method calls or ignore extra hash keys in splat
       [not found] <redmine.issue-16115.20190822120133@ruby-lang.org>
@ 2019-08-22 12:01 ` kimmo.lehto
  2019-08-22 19:56 ` [ruby-core:94485] " shevegen
  2019-08-23  0:53 ` [ruby-core:94489] " mame
  2 siblings, 0 replies; 3+ messages in thread
From: kimmo.lehto @ 2019-08-22 12:01 UTC (permalink / raw)
  To: ruby-core

Issue #16115 has been reported by kke (Kimmo Lehto).

----------------------------------------
Feature #16115: Keyword arguments from method calls or ignore extra hash keys in splat
https://bugs.ruby-lang.org/issues/16115

* Author: kke (Kimmo Lehto)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Just a thought, feel free to insta-close as stupid.

Currently you can do this:

```
def hello(who:)
  puts "Hello, #{who}"
end

opts = { who: 'world' }
hello(who)
```

Or: 

```
def hello(who:, **_extra_opts) # without eating extra args, you get ArgumentError (unknown keyword: foo)
  puts "Hello, #{who}!"
end

hello(**{ who: 'world', foo: 'bar' })
```

Or even this:

```
def hello(_obj = nil, who: _obj&.who || raise(ArgumentError, "missing who:"))
  puts "Hello, #{who}!"
end

hello(OpenStruct.new(who: 'world'))
```

1) What if when you passed an object as an argument to a method that only accepts keyword arguments, the methods listed would be called? Then you could do:

```
require 'ostruct'
ostruct = OpenStruct.new(who: 'world, foo: 'bar')

def hello(who:)
  puts "Hello, #{who}!"
end

hello(ostruct)
```

2) Or perhaps add some sort of "triple splat" that would either a) do the method calling thing described above or b) do the regular hash splatting like `**` but ignore any keys present that are not listed as keyword arguments:

```
require 'ostruct'
ostruct = OpenStruct.new(who: 'world', foo: 'bar')

def hello(who:)
  puts "Hello, #{who}!"
end

# a:  
hello(***ostruct)  # would call ostruct.who to figure out `who:`

# or b: (currently with ** raises ArgumentError (unknown keyword: foo))
hello(***{ who: 'world', foo: 'bar' }) # would ignore any extra keys 
```

I think this could open up some possibilities (or a can of worms). 




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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:94485] [Ruby master Feature#16115] Keyword arguments from method calls or ignore extra hash keys in splat
       [not found] <redmine.issue-16115.20190822120133@ruby-lang.org>
  2019-08-22 12:01 ` [ruby-core:94480] [Ruby master Feature#16115] Keyword arguments from method calls or ignore extra hash keys in splat kimmo.lehto
@ 2019-08-22 19:56 ` shevegen
  2019-08-23  0:53 ` [ruby-core:94489] " mame
  2 siblings, 0 replies; 3+ messages in thread
From: shevegen @ 2019-08-22 19:56 UTC (permalink / raw)
  To: ruby-core

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


> I think this could open up some possibilities (or a can of worms).

Some can call it a feature, other may call it a bug. :-)

In regards to keyword arguments, though, I would wait a bit and see
how/if https://bugs.ruby-lang.org/issues/14183 is decided upon (or
not) at the upcoming dev meeting (at
https://bugs.ruby-lang.org/issues/14183).

In my opinion it would be best to not put more and more complexity
into keyword arguments and related activities, such as the proposal
here by suddenly retrofitting it into calling methods:

    def hello(who:)
      puts "Hello, #{who}!"
    end

The net benefit to me here appears to be only that you can save a few
characters (since you don't have to be explicit about the method) but
that seems to be at odds, or at the least strange, and mostly implied
behaviour. You can ask matz about his opinion of course but I think this
should be decided after the other issues have been decided; and my personal
opinion is to rather not want to make this all more complex. The
complexity associated with this was already a source of bugs and
confusion; I think jeremy events pointed this out before.

    hello(***{ who: 'world', foo: 'bar' }) # would ignore any extra keys 

As for triple-splat, I am against this; it seems to add more complexity 
for no real gain. If we have triple splats, do we then want quad-splats,
and quadriple splats, all with special meaning?

----------------------------------------
Feature #16115: Keyword arguments from method calls or ignore extra hash keys in splat
https://bugs.ruby-lang.org/issues/16115#change-80920

* Author: kke (Kimmo Lehto)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Just a thought, feel free to insta-close as stupid.

Currently you can do this:

```
def hello(who:)
  puts "Hello, #{who}"
end

opts = { who: 'world' }
hello(who)
```

Or: 

```
def hello(who:, **_extra_opts) # without eating extra args, you get ArgumentError (unknown keyword: foo)
  puts "Hello, #{who}!"
end

hello(**{ who: 'world', foo: 'bar' })
```

Or even this:

```
def hello(_obj = nil, who: _obj&.who || raise(ArgumentError, "missing who:"))
  puts "Hello, #{who}!"
end

hello(OpenStruct.new(who: 'world'))
```

1) What if when you passed an object as an argument to a method that only accepts keyword arguments, the methods listed would be called? Then you could do:

```
require 'ostruct'
ostruct = OpenStruct.new(who: 'world, foo: 'bar')

def hello(who:)
  puts "Hello, #{who}!"
end

hello(ostruct)
```

2) Or perhaps add some sort of "triple splat" that would either a) do the method calling thing described above or b) do the regular hash splatting like `**` but ignore any keys present that are not listed as keyword arguments:

```
require 'ostruct'
ostruct = OpenStruct.new(who: 'world', foo: 'bar')

def hello(who:)
  puts "Hello, #{who}!"
end

# a:  
hello(***ostruct)  # would call ostruct.who to figure out `who:`

# or b: (currently with ** raises ArgumentError (unknown keyword: foo))
hello(***{ who: 'world', foo: 'bar' }) # would ignore any extra keys 
```

I think this could open up some possibilities (or a can of worms). 




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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:94489] [Ruby master Feature#16115] Keyword arguments from method calls or ignore extra hash keys in splat
       [not found] <redmine.issue-16115.20190822120133@ruby-lang.org>
  2019-08-22 12:01 ` [ruby-core:94480] [Ruby master Feature#16115] Keyword arguments from method calls or ignore extra hash keys in splat kimmo.lehto
  2019-08-22 19:56 ` [ruby-core:94485] " shevegen
@ 2019-08-23  0:53 ` mame
  2 siblings, 0 replies; 3+ messages in thread
From: mame @ 2019-08-23  0:53 UTC (permalink / raw)
  To: ruby-core

Issue #16115 has been updated by mame (Yusuke Endoh).


Thank you for proposing ideas.  They are interesting to me.

As you said in your second example, it is only possible in callee side: changing the method definition to accept a dummy `**` argument.

```
def hello(who:, **)
end

hello(who: "world", foo: "bar")
```

It is difficult to do so in the caller side.  (It is theoretically possible by using `Method#parameters`, but it is an evil magic.)


> 1) What if when you passed an object as an argument to a method that only accepts keyword arguments, the methods listed would be called?

I have never thought this.  Very interesting, but it looks a too big semantics change just for solving the problem.

> 2) Or perhaps add some sort of "triple splat" that would either a) do the method calling thing described above or b) do the regular hash splatting like ** but ignore any keys present that are not listed as keyword arguments:

I have never thought this, nethier.  I have never spent time to consider it yet, but as my first impression, it looks a good idea.  I'd like to hear opinions from matz and people.

----------------------------------------
Feature #16115: Keyword arguments from method calls or ignore extra hash keys in splat
https://bugs.ruby-lang.org/issues/16115#change-80924

* Author: kke (Kimmo Lehto)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Just a thought, feel free to insta-close as stupid.

Currently you can do this:

```
def hello(who:)
  puts "Hello, #{who}"
end

opts = { who: 'world' }
hello(who)
```

Or: 

```
def hello(who:, **_extra_opts) # without eating extra args, you get ArgumentError (unknown keyword: foo)
  puts "Hello, #{who}!"
end

hello(**{ who: 'world', foo: 'bar' })
```

Or even this:

```
def hello(_obj = nil, who: _obj&.who || raise(ArgumentError, "missing who:"))
  puts "Hello, #{who}!"
end

hello(OpenStruct.new(who: 'world'))
```

1) What if when you passed an object as an argument to a method that only accepts keyword arguments, the methods listed would be called? Then you could do:

```
require 'ostruct'
ostruct = OpenStruct.new(who: 'world, foo: 'bar')

def hello(who:)
  puts "Hello, #{who}!"
end

hello(ostruct)
```

2) Or perhaps add some sort of "triple splat" that would either a) do the method calling thing described above or b) do the regular hash splatting like `**` but ignore any keys present that are not listed as keyword arguments:

```
require 'ostruct'
ostruct = OpenStruct.new(who: 'world', foo: 'bar')

def hello(who:)
  puts "Hello, #{who}!"
end

# a:  
hello(***ostruct)  # would call ostruct.who to figure out `who:`

# or b: (currently with ** raises ArgumentError (unknown keyword: foo))
hello(***{ who: 'world', foo: 'bar' }) # would ignore any extra keys 
```

I think this could open up some possibilities (or a can of worms). 




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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-08-23  0:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-16115.20190822120133@ruby-lang.org>
2019-08-22 12:01 ` [ruby-core:94480] [Ruby master Feature#16115] Keyword arguments from method calls or ignore extra hash keys in splat kimmo.lehto
2019-08-22 19:56 ` [ruby-core:94485] " shevegen
2019-08-23  0:53 ` [ruby-core:94489] " mame

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).