帮助在Ruby中将符号解释为哈希值?

时间:2011-08-30 22:34:38

标签: ruby hash symbols

总Ruby noob。我正在经历Zed Shaw的LRTHW,而且我仍然坚持哈希练习。我对这段代码没有任何意义,也无法在网上找到任何类似的内容。

cities = {'CA' => 'San Francisco', 'MI' => 'Detroit', 'FL' => 'Jacksonville'}

cities['NY'] = 'New York'
cities['OR'] = 'Portland'

def find_city (map, state)
  if map.include? state
    return map[state]
  else
    return "Not found."
  end
end

cities[:find] = method(:find_city)

while true
  print "State? (Enter to quit) "
  state = gets.chomp

  break if state.empty?

  puts cities[:find].call(cities, state)
end

基本上,我只是卡住了。我无法在输入状态和返回城市之间建立联系。任何愚蠢的解释都将不胜感激。

3 个答案:

答案 0 :(得分:2)

符号表示自身,正如0表示0 - 符号仅等于自身。 (请注意:foo == "foo"为false,因此hash[:foo]永远不会引用hash["foo"]对,即使两者都可以评估相同的对象。)

所以cities[:find]只是没有多大意义,它将数据(哈希映射状态与大城市)混淆了对数据的操作......它可能也是cityFindFunction而不是cities = {'CA' => 'San Francisco', 'MI' => 'Detroit', 'FL' => 'Jacksonville'} def find_city (map, state) if map.include? state # if this hash contains the state, e.g. "CA" then # return a big city in the state return map[state] else # otherwise return a diagnostic message return "Not found." end end while true print "State? (Enter to quit) " state = gets.chomp break if state.empty? # this is a method invocation, no need for "call"! puts find_city(cities, state) end 。但是,因为使用方法本身很好(不需要在这里转换为函数!),请考虑这种简化:

nil

这可以通过返回find_city(cities, state)而不是“未找到”进一步简化。 (让调用者处理它)或使用哈希的默认值。无论如何,我希望上面的内容显示了正在做的事情的“本质”。

快乐的编码。


关于方法与方法与功能的简要介绍。

在Ruby中,方法不是第一类值。相反,它们是给定对象作出反应的“消息”。上面的self.__send__(:find_city, cities, state) 方法调用对于__send__来说非常方便。 (好吧,不是因为call本身就是一个方法调用,但这是内部发生的事情的要点......; - )

另一方面,

函数(类型Proc)和类型Method的对象只是对象。因此,与方法不同,它们是“一等值”。要调用/应用 函数/方法对象,请使用{{1>} 方法函数/方法 em>)使用给定参数执行函数并计算函数/方法返回值。

method 方法返回方法对象 - 绑定到对象method的实例上 em> - 对于给定的方法

希望在某种程度上解释其余部分; - )

答案 1 :(得分:2)

这里有一个哈希(城市),有3对密钥=>值

cities = {'CA' => 'San Francisco', 'MI' => 'Detroit', 'FL' => 'Jacksonville'}

您可以通过键访问该值:

puts cities['CA']  #=>  'San Francisco'

现在我们添加两个新对。

cities['NY'] = 'New York'
cities['OR'] = 'Portland'

整个哈希将是:

p cities #=> {'CA' => 'San Francisco', 'MI' => 'Detroit', 'FL' => 'Jacksonville', 'NY' => 'New York', 'OR' => 'Portland'}

现在它定义了一个名为find_city的方法。它需要哈希和密钥。

def find_city (map, state)
  # if hash has the key, return its value. (There are better ways to do it.)
  if map.include? state
    return map[state]
  else
    return "Not found."
  end
end

这里有我见过的最糟糕的Ruby代码。

cities[:find] = method(:find_city)

好的,该代码获取方法find_city并将其转换为Method对象,该对象可以分配给变量。但是,它不是使用普通的局部变量,而是存储在cities哈希的值中!

该对象与方法类似,但它是一个对象而不是方法,必须使用call调用(在Ruby 1.8.7中)。

我将使用一个名为my_meth的变量(可以是任何名称)来更好地解释。

# get the method find_city and turns it into an object assigned to my_meth
my_meth = method(:find_city)

while true
  print "State? (Enter to quit) "
  state = gets.chomp

  break if state.empty?

  # here we use find_city on the cities hash.
  puts my_meth.call(cities, state)
end

puts my_meth.class

但是,代替使用变量,原始代码将Method对象存储在cities哈希上。所以,城市将是:

cities[:find] = method(:find_city)
p cities #=> {'CA' => 'San Francisco', 'MI' => 'Detroit', 'FL' => 'Jacksonville', 'NY' => 'New York', 'OR' => 'Portland', :find => (the Method object)}

因此,您可以访问find_citycities[:find].call

答案 2 :(得分:1)

它并不那么难。

  • 前4行用缩写=>填充哈希值国家名称
  • 然后定义一个方法find_city,它获取一个地图和一个缩写,并打印相应的名称。
  • 之后,您将名为find_city的方法放在哈希城市中,密钥为:find。
  • cities [:find] .call(cities,state)只使用参数调用以前保存的方法。

不是在这里使用符号,而是至少对哈希部分使用字符串或整数。此外,您可以使用方法(“find_city”)而不是方法(:find_city)

您只需要了解基本的ruby逻辑,并且可以引用方法作为对象。