I was reading Why's (Poignant) guide to Ruby, and came across a method that didn't quite work out as expected. The method is aimed to return a value (from a hash) for a given string, somewhat like an encoder-decoder. Originally, the method was written inside a class String
, but I modified it to change the classname. Here's the code:
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
To run this code, the book simply uses "Paij-ree".name_significance
. But when I tried doing the same thing, I got a NoMethodError - in <top (required)>: undefined method NameReplacer for "Paij-ree":String (NoMethodError)
.
I got the same error when I tried: print "Paij-ree".NameReplacer.new.name_significance
I assume this worked in the book because the method was written in a class String
, which, I guess, would be equal to having this method in Ruby's String
class. Due to that, something like "paij-ree".name_significance"
would not throw an error, because the "paij-ree"
would be a String
object, and String
class does have the method name_significance
.
However, how do I accomplish this with my current code? Apologies if this question seems stupid.
Three approaches with same result:
# 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
means the object the method is defined on. You can't use self
in the NameReplacer
class to refer to a string, it will be the NameReplacer
instance (inside an instance method like yours).