如何在 Ruby 中将关键字参数默认设置为未定义

How do I set a keyword arg to default to undefined in Ruby

我有以下代码

def thing(item: "yeah")
  puts item == nil
end  
def thing2(item: nil)
  thing(item: item)
end
thing2()

我希望看到 false,因为我希望传递给 thingnil 被视为未定义的 item 参数,但是,我看到 true。我怀疑这是因为,像 JS 一样,ruby 将 nilundefined 分开。那么有没有一种方法可以将值默认为 undefined 而不是 nil

我当前基于已接受答案的最终版本如下所示...

def default_item 
  "yeah" 
end
def default_other 
  "other" 
end

def thing(item: default_item(), other: default_other())
  puts item + " " + other
end  
def thing1(other: default_other())
  thing(other: other)
end  
def thing2(item: default_item())
  thing(item: item)
end
thing1()
thing2()
thing1(other:"Is Other")
thing2(item:"Is Item")
# fail with argument exception
# thing1(item:"Not Item")
# thing2(other:"Not Other")

Code Example

(returning 一个值的方法更多是基于它需要实际 return 一个实例值)

我仍然不喜欢到处都是 item: default_item(),所以我愿意接受更好的解决方案。

在Ruby,nil和缺席是两种截然不同的事情。

thing2 使用 item=nil 调用 thing 时,thing 意识到 item 存在,但其值是 nil。因此检查 item==nil returns true.

我认为您的两个最佳选择是手动检查 nil,并且只使用与其他方法相同的默认值:

选项 1:

def thing(item: "yeah")
  puts item == nil
end  
def thing2(item: nil)
  if item!=nil
      thing(item: item)
  else
      thing()
  end
end
thing2()

选项 2:

$DEFAULT = "yeah"
def thing(item: $DEFAULT)
  puts item == nil
end  
def thing2(item: $DEFAULT)
  thing(item: item)
end
thing2()

您调用 thing2(),因此 thing2 中的 item 获得其默认值 nil。然后它给 thing。所以 thing 中的 item 也是 nil。如果您希望它成为 "yeah",那么您需要真正 调用 thing 而没有 item 的值。不适用于 nil 值。

一种方法是使用散列参数而不是关键字参数:

def thing(item: "yeah")
  puts item == nil
end  
def thing2(options = {})
  thing(options)
end
thing2()
thing2(item: nil)

thing2() 打印 false 因为 thing2 没有得到 item 值,因此不会给 item 值=16=]。所以thing使用默认的"yeah".

它为 thing2(item: nil) 打印 true 因为 thing2 确实得到一个 item 值并将它转发给 thing,它是 nil.

不确定这是否是个好主意,我想这取决于您的实际用例。

编辑:正如@SergioTulentsev 评论的那样,您仍然可以使用关键字参数:

def thing(item: "yeah")
  puts item == nil
end  
def thing2(**kwargs)
  thing(**kwargs)
end
thing2()
thing2(item: nil)

这可能更好,始终如一地在任何地方使用关键字参数。