示例代码中“end”的奇怪用法

时间:2014-06-02 16:06:31

标签: ruby

浏览this我注意到我之前从未见过的第83行。end.map(&:chomp)所以end是一个对象? (我意识到这可能是100%错误。)有人可以解释那里有什么以及如何运作?究竟有什么优势?

3 个答案:

答案 0 :(得分:3)

不,end不是一个对象,但是object.some_method do ... end是一个对象(或者更确切地说它是一个对象) - 即some_method方法返回的对象。

因此,如果您执行object.some_method do ... end.some_other_method,则会在some_other_method返回的对象上调用some_method

答案 1 :(得分:2)

您所指的完整代码段如下:

def initialize(dict_file)
  @dict_arr = File.readlines(dict_file).select do |word|
    !word.include?("-") && !word.include?("'")
  end.map(&:chomp)
end

请注意,您正在谈论的end是从第2行开始的块的结尾(它与第2行的do匹配)。

也许如果你看到它括起来,并用花括号重写,它会更有意义:

def initialize(dict_file)
  @dict_arr = (File.readlines(dict_file).select { |word|
    !word.include?("-") && !word.include?("'")
  }).map(&:chomp)
end

答案 2 :(得分:1)

逐步检查Ruby正在做什么通常很有帮助。让我们看看方法ComputerPlayer#initialize

的用途
def initialize(dict_file)
  @dict_arr = File.readlines(dict_file).select do |word|
    !word.include?("-") && !word.include?("'")
  end.map(&:chomp)
end

首先,创建一个文件:

File.write("my_file", "cat\ndog's\n")

执行时:

ComputerPlayer.new("my_file")

类方法IO#readlines将发送到File,返回数组a

a = File.readlines("my_file")
  #=> ["cat\n", "dog's\n"]

Enumerable#select被发送到数组a以创建枚举器:

b = a.select
  #=> #<Enumerator: ["cat\n", "dog's\n"]:select>

我们可以将此枚举器转换为数组,以查看它将传递给它的块:

b.to_a
=> ["cat\n", "dog's\n"]

通过向方法each发送带有块的枚举器来调用它,并返回一个数组c

c = b.each { |word| !word.include?("-") && !word.include?("'") }
  #=> ["cat\n"]

最后,我们将带有参数&:chomp的{​​{3}}(转换为proc的方法String#chomp)发送到数组c

c.map(&:chomp)
  #=> ["cat"]

最后一点:您可以通过尽量减少!的使用来提高清晰度。例如,而不是

...select do |word|
   !word.include?("-") && !word.include?("'")

考虑

...reject do |word|
   word.include?("-") || word.include?("'")

您也可以使用正则表达式。