【问题标题】:adding a keyword without a definition in a Ruby hash [closed]在 Ruby 哈希中添加没有定义的关键字 [关闭]
【发布时间】:2013-10-05 19:26:05
【问题描述】:

我有以下块允许我添加带有关键字和定义的整个条目:

class Dictionary

  def initialize
    @d = {}
  end

  def entries
    @d
  end

  def add(entry)
    (entry).each {|k,v=nil| 
      @d[k] = v
    }
  end

  def keywords
    @d.keys
  end

end

我希望能够添加没有定义的关键字(添加键,但没有值)。我尝试在上面的块中设置 v=nil ,但它仍然失败。这是我在针对 Rspec 运行时遇到的错误:

Dictionary
  is empty when created
  can add whole entries with keyword and definition
  add keywords (without definition) (FAILED - 1)

Failures:

  1) Dictionary add keywords (without definition)
     Failure/Error: @d.add('fish')     
     NoMethodError:
      undefined method `each' for "fish":String
   # ./11_dictionary/dictionary.rb:13:in `add'
   # ./11_dictionary/dictionary_spec.rb:27:in `block (2 levels) in <top (required)>' 

最后,这是它需要通过的 rspec 测试:

it 'add keywords (without definition)' do
  @d.add('fish')
  @d.entries.should == {'fish' => nil}
  @d.keywords.should == ['fish']
end

【问题讨论】:

  • 不应该使用def add(entry, val=nil) @d[entry]=val unless @d[entry] end 来解决问题吗?还是我不明白这个问题?
  • 谢谢,但我在尝试时遇到了错误。我认为 add 方法只需要一个参数而不是两个。

标签: ruby hash rspec key


【解决方案1】:

假设entry可以是像'fish' =&gt; 1这样的Hash或者像'fish'这样的String

def add(entry)
  if entry.is_a? Hash
     (entry).each {|k,v=nil| 
        @d[k] = v
     }
  elsif entry.is_a? String
    @d[entry] = nil
  else 
    raise "wrong input type in add entry"
  end
end

您可以类似地处理不同形式的输入。例如处理条目数组检查是否entry.is_a? Array,然后进行相应处理。

也就是说,编码此方法的一种更简洁的方法可能是将键和值作为@steenslag 建议的显式输入。

def add_key(k,v=nil)
   @d[k] = v
end

然后你可以调用add("fish", 1)这样的方法来添加一个值或add('fish')来添加一个值。

要添加多个键,请定义另一个方法,例如:

def add_keys(opts={})
  opts.map{|k,v| @d[k] = v}
end

这可以称为add_keys("fish" =&gt; 1, "dog" =&gt; 2, "mouse" =&gt; nil)。这种表示法与 RoR 的 update_attributeupdate_attributes 方法相同。

【讨论】:

  • 这成功了!谢谢。我是新手,所以我什至不知道 .is_a?方法。
  • 您可以考虑在此处使用case 语句:case entry ... when Hash ... when String ... else ... end。 (case 使用 ===
  • @user2785673 查看更新的答案以获取更多信息。
【解决方案2】:

你这是什么意思?

def add(entry)
  (entry).each {|k,v=nil|
    @d[k] = v
  }
end

由于您传递单个元素,因此主体可以简单地是这样的:

def add(entry)
  @d[entry] = nil
end

【讨论】:

  • 谢谢,但是当我尝试这个时,之前的测试没有通过(这是接受关键字和定义的测试)。看起来我需要能够接受 1. 空哈希(适用于我的原始代码),2. 关键字和定义(也适用),而且 3. 仅关键字(没有定义)......跨度>
【解决方案3】:
def add(key, value=nil)
  @d[key] = value
end

应该做的伎俩。

【讨论】:

  • 您好,谢谢,但类似于上面的评论,当我尝试这样做时,它会失败之前应该接受键和值的测试。我必须找到一种方法让 add 方法接受键值条目以及键。
  • 尝试像这样调用方法:@d.add("fish, 1)@d.add("dog")
  • 不幸的是,该方法只能接受一个参数。它看起来像上面的解决方案,使用 .is_a?方法奏效了。再次感谢
猜你喜欢
  • 2013-09-30
  • 1970-01-01
  • 2014-04-12
  • 2014-05-30
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多