【问题标题】:Ruby named parameters with keywords带有关键字的 Ruby 命名参数
【发布时间】:2015-01-09 09:00:07
【问题描述】:

我喜欢使用这样的方法签名:

def register(something, on:, for:)

这可行,但我不知道如何使用“for”而不导致语法错误!相当烦人,有人知道解决这个问题的方法吗?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    问题不在于您发布的方法定义行,问题在于方法体内for变量的使用。由于for 是保留字,因此不能将其用作普通变量名,但可以将其用作散列的一部分。在您的情况下,这意味着您必须使用任意关键字参数(**opts),但您可以在方法调用中使用关键字参数for:。如果密钥不存在,您可能需要提出ArgumentError 来模拟您在上面发布的方法签名的行为。

    def register(something, on:, **opts)
      raise ArgumentError, 'missing keyword: for' unless opts.has_key?(:for)
      for_value = opts[:for]
    
      puts "registering #{something} on #{on} for #{for_value}"
    end
    
    register 'chocolate chips', on: 'cookie'
    # ArgumentError: missing keyword: for
    
    register 'chocolate chips', on: 'cookie', for: 'cookie monster'
    # registering chocolate chips on cookie for cookie monster
    

    【讨论】:

    • 这是一种方法 :) 我希望不要偏离命名的参数格式
    • 我知道它不是很漂亮,但它可以完成工作并且调用语法同样干净
    【解决方案2】:

    在 Ruby 中,for 是一个保留关键字 - 看起来您只是不能以其他方式使用它们,而不是它们本来的用途。 这就是保留关键字的全部目的。

    在 Ruby 中保留关键字的其他资源:

    UPD

    实际上,您仍然可以使用 :for 符号作为哈希中的键(比方说,选项哈希),因此,您可以这样写:

    def test(something, options = {})
      puts something
      puts options.values.join(' and ')
    end 
    

    它的作用就像魅力:

    [4] pry(main)> test 'arguments', :for => :lulz, :with => :care, :while => 'you are writing code' 
    arguments
    lulz and care and you are writing code
    

    【讨论】:

    • 我知道它是一个关键字,我在标题中提到过。我问有没有办法解决。通过当前绑定或其他方式动态访问它的某种方式?
    • @MichaelBaldry 查看更新的部分 - 是否足以供您使用,或者您的意思是其他方式?顺便说一句,以我的拙见,以这种方式使用关键字可以增加“WTF?!”的数量每行。 ;)
    • 两个链接都没有提到__ENCODING__。另外,从 2.2.0 开始,Ruby 自带了一个官方文档:$ ri ruby:keywords
    • 我知道它会增加 WTF/L,我只是好奇 :)
    【解决方案3】:
    binding.local_variable_get(:for)
    

    是我的想法。我认为仅适用于 ruby​​ 2.1+。

    注意:不要这样做,我只是对你如何绕过它感兴趣,你可能应该把你的命名参数命名为别的 :)

    【讨论】:

      猜你喜欢
      • 2021-08-24
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 2013-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      相关资源
      最近更新 更多