关于Ruby中符号和实例方法的一些问题

时间:2016-09-21 06:49:20

标签: ruby-on-rails ruby web methods symbols

我目前正在尝试学习红宝石'学习红宝石的艰难之路' 这是我的问题......

以下代码来自练习40:

#ticket-test li

我玩了代码,最后了解它是如何工作的。 但我仍然不明白两件事:

...第一

在代码中间, 它定义了一个变量

.length

正如我现在所知,var tickets = $("#ticket-test li"); function wrapListItems (el, num, i = 0, n = num) { if (n <= tickets.length) { el.slice(i, n).wrapAll("<ul>").parent().wrap("<li>"); i += num; n += num; wrapListItems(el, num, i, n); } }; wrapListItems(tickets, 10);(冒号)声明了一个符号。 我想知道将变量命名为<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> </script> <ul id="ticket-test"> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> <li>001 Location</li> </ul>是一种更好的做法 而不是在这种情况下使用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

我不太确定这些差异是什么,或者对于大多数rubyist来说它可读性很高?

第二个也是同一条线。

cities[:find] = method(:find_city)

我知道它允许我调用:方法。 但同样,为什么我必须在cities[:find]之前加上冒号? 这段代码是否意味着解析我放入符号的参数?

4 个答案:

答案 0 :(得分:2)

我必须说学习Ruby艰难的方式给了我们一个真正非常好的例子,说明我们不应该做什么。没有rubyist会在他/她的项目中输入这样的代码。这段代码令人困惑,难以辨认,并且是对元编程的滥用。

无论如何,我为你解剖了这段代码。

令人困惑的部分从这一行开始:

cities[:find] = method(:find_city)

让我们看一下=的右侧。它调用一个名为method的方法,正如您可能猜到的,方法调用的返回值是方法find_city,更确切地说,是一个包装方法Method的对象find_city 1}}及其范围。然后该方法存储在哈希cities中,并以符号:find作为键。所以cities的价值现在变为

{
  'CA'=> 'San Francisco', 
  'MI'=> 'Detroit', 
  'FL'=> 'Jacksonville',
  'NY' => 'New York',
  'OR' => 'Portland',
  :find => #<Method:main.find_city>
}

你可以看到最后一个键值对真的很奇怪,它不应该存在,因为哈希cities应该只存储状态及其大写字母。赫克!

然后这就是更奇怪的表达式cities[:find].call(cities, state)。让我们看看这是如何工作的。

cities[:find]只是从哈希中检索Method对象(还记得它包装的方法吗?)

cities[:find].call(cities, state)find_city对象包装的范围内调用它包装的方法Method,这是顶级对象(又名main), Method#call返回返回包含的方法。所以这个表达式只是find_city(cities, state),用外来风格写成。

答案 1 :(得分:0)

  

cities[:find] = method(:find_city)

此处,cities是一个哈希,method(:find_city)返回的方法对象被分配给作为符号的哈希键find

我认为这取决于您和您正在编写此程序的程序的上下文。

简单的method_var = method(:find_city)也适用于此。

  

method(:find_city)

     

我知道它允许我调用find_city方法。但是,为什么我必须在find_city之前放一个冒号?这段代码是否意味着解析我放入符号的参数?

在这里,您将方法名称作为参数传递,您必须将其作为symbolstring传递。

答案 2 :(得分:0)

在Ruby中,method方法创建一个方法对象。这允许您在代码中传递它,稍后使用Method对象上的.call方法调用它。 由于调用method(my_method)会评估my_method并将结果传递给method(...),因此您需要一种方法来告诉method方法使用哪种方法。这就是为什么你基本上将方法名称作为符号传递到method方法的原因:D

答案 3 :(得分:-2)

所以它实际上定义了一个proc,并使:findfind_city类似于键和值...可能......