Project

General

Profile

Actions

Bug #11771

closed

unable to pass keyargs to []=

Added by bughit (bug hit) almost 10 years ago. Updated almost 10 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:71836]

Description

module Foo
  def self.[]=(key, val, option: nil)

  end
end

Foo[:key] = 1 # ok


Foo[:key, option: 1] = 1 # wrong number of arguments (3 for 2)

if you declare the []= params using *


module Bar
  def self.[]=(*args)
    p args
  end
end

Bar[:key, option: 1] = 1 # args: [:key, {:option=>1}, 1]

the args end up [:key, {:option=>1}, 1] which seems wrong since the keyargs hash is supposed to be last

Updated by normalperson (Eric Wong) almost 10 years ago

Affects back to 2.0 (when keyword args were introduced),
so this doesn't seem to be an optimization bug introduced in 2.1/2.2

I'm actually not sure about the specs and if there's some special case
for kwargs interacting with aref/aset...

For instance, frequently use the 'sequel' API to write stuff like:

DB[:tbl][id: 123]

(I've been doing this since before keyword args were introduced)

Updated by bughit (bug hit) almost 10 years ago

Eric Wong wrote:

Affects back to 2.0 (when keyword args were introduced),
so this doesn't seem to be an optimization bug introduced in 2.1/2.2

I'm actually not sure about the specs and if there's some special case
for kwargs interacting with aref/aset...

The problem here is that the []= syntax compiled into a method dispatch where positional value arg is passed last, after keyargs, something you can't even do in ruby.

you can simulate the bug with a plain method:


def foo(key, val, option: nil)
end

foo(:key, 1, option: 1) # ok
foo(:key, {option: 1}, 1) # wrong number of arguments (3 for 2)

Updated by matz (Yukihiro Matsumoto) almost 10 years ago

  • Status changed from Open to Closed

Pending, for several reasons:

(1) compatibility. a[a,foo:1]=v is valid code. changing behavior may crash existing code.
(2) you can delegate to other method e.g.

def opt_aset(k,v,option:nil)
  ...
end

def []=(k,opt={},v)
  opt_aset(k,v,*opt)
end

Matz.

Updated by bughit (bug hit) almost 10 years ago

Yukihiro Matsumoto wrote:

Pending, for several reasons:

(1) compatibility. a[a,foo:1]=v is valid code. changing behavior may crash existing code.
(2) you can delegate to other method e.g.

def opt_aset(k,v,option:nil)
  ...
end

def []=(k,opt={},v)
  opt_aset(k,v,*opt)
end

Matz.

def []=(k,opt={},v) feels wrong because you're taking a dependency on incorrect behavior (method dispatch that puts a positional arg after the keyargs) Why not correct it for 3.0?

Updated by matz (Yukihiro Matsumoto) almost 10 years ago

I don't say anything about 3.0 for now.
But things are more complicated than you imagine.

Matz.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0