NoMethodError: Calling an instance method correctly in Ruby with the use of self

NoMethodError: Calling an instance method correctly in Ruby with the use of self

我正在阅读 Ruby 的 Why(凄美)指南,并发现了一种方法,但效果不如预期。该方法旨在 return 给定字符串的值(来自哈希),有点像编码器-解码器。本来这个方法是写在一个class String里面的,但是我修改了它,改成了class这个名字。这是代码:

class NameReplacer
  @@syllables = [

      {"Paij" => "Personal","Gonk" => "Business", "Blon" => "Slave", "Stro" => "Master", "Wert" => "Father", "Onnn" => "Mother"},
      {"ree" => "AM", "plo" => "PM"}
  ]

  # method to determine what a certain name of his means
  def name_significance
    # split string by -
    parts = self.split("-")
    # make duplicate of syllables
    syllables = @@syllables.dup
    signif = parts.collect {|name| syllables.shift[name]}
    #join array returned by " " forming a string
    signif.join(" ")
  end
end

到运行这段代码,书上简单的用了"Paij-ree".name_significance。但是当我尝试做同样的事情时,我得到了一个 NoMethodError - in <top (required)>: undefined method NameReplacer for "Paij-ree":String (NoMethodError)

我尝试时遇到了同样的错误:print "Paij-ree".NameReplacer.new.name_significance

我认为这在书中可行,因为该方法是在 class String 中编写的,我猜这等同于在 Ruby 中使用此方法Stringclass。因此,像 "paij-ree".name_significance" 这样的东西不会抛出错误,因为 "paij-ree" 将是一个 String 对象,而 String class 确实有方法 name_significance.

但是,如何使用我当前的代码完成此操作?如果这个问题看起来很愚蠢,我们深表歉意。

三种方法结果相同:

# monkey-patching a class
class String
  def appendFoo
    self + "foo"
  end
end

"a".appendFoo
# => "afoo"

# using an external class method
class FooAppender
  def self.appendFoo(string)
    string + "foo"
  end
end

FooAppender.appendFoo("a")
# => "afoo"

# using an external instance method
class StuffAppender
  def initialize(what)
    @what = what
  end

  def append_to(string)
    string + @what
  end
end

new StuffAppender("foo").append_to("a")
# => "afoo"

self 表示定义该方法的对象。您不能在 NameReplacer class 中使用 self 来引用字符串,它将是 NameReplacer 实例(在像您这样的实例方法中)。

正如其他人所提到的,该代码取决于字符串 class。您的另一种选择是使用 class 扩展字符串 class ,如下所示:

class NameReplacer < String    
  @@syllables = [
    {
      "Paij" => "Personal",
      "Gonk" => "Business",
      "Blon" => "Slave",
      "Stro" => "Master",
      "Wert" => "Father",
      "Onnn" => "Mother"
    },
    {
      "ree" => "AM",
      "plo" => "PM"
    }
  ]

  # method to determine what a certain name of his means
  def name_significance
    # split string by -
    parts = self.split("-")
    # make duplicate of syllables
    syllables = @@syllables.dup
    signif = parts.collect {|name| syllables.shift[name]}
    #join array returned by " " forming a string
    signif.join(" ")
  end
end

然后像这样使用它:

p = NameReplacer.new("Paij-ree")
puts p.name_significance