Ruby和公共\u方法\u已定义?:奇怪的行为

Ruby和公共\u方法\u已定义?:奇怪的行为,ruby,Ruby,在阅读《红字作家》一书时,我遇到了一些奇怪的行为。代码背后的想法是使用自己的方法。我唯一不能理解的是,为什么要执行这段代码,因为我没有任何Person.all_和定义的类方法,这意味着self.public_方法(attr)返回true(attr是friends,然后是嗜好) 这是可以理解的,因为没有什么可执行的 嗯,是因为我有朋友和爱好的访问者吗?但是我认为它们只能在实例中访问,而不能在类对象级别上访问。假设粘贴到问题中的代码就是您正在运行的代码,那么问题是初始化中的键入错误: def in

在阅读《红字作家》一书时,我遇到了一些奇怪的行为。代码背后的想法是使用自己的方法。我唯一不能理解的是,为什么要执行这段代码,因为我没有任何Person.all_和定义的类方法,这意味着self.public_方法(attr)返回true(attr是friends,然后是嗜好)

这是可以理解的,因为没有什么可执行的



嗯,是因为我有朋友和爱好的访问者吗?但是我认为它们只能在实例中访问,而不能在类对象级别上访问。

假设粘贴到问题中的代码就是您正在运行的代码,那么问题是
初始化中的键入错误:

def initialize(
mame
)应该是
def initialize(
name

如果参数
name
的名称输入错误,则会导致行
@name=name
,而不是含义

“将
@name
设置为参数值”

意指

“将
@name
设置为方法
name
(您的attr读取器)返回的值”(当然是
nil
,因为尚未设置该值)


因此,所有披头士乐队的名字都没有设置,输出是Paul和Ringo爱好的两个朋友,但所有名字都是空的。

假设粘贴到问题中的代码就是您正在运行的代码,那么问题是
initialize
中的键入错误:

def initialize(
mame)应该是
def initialize(
name

如果参数
name
的名称输入错误,则会导致行
@name=name
,而不是含义

“将
@name
设置为参数值”

意指

“将
@name
设置为方法
name
(您的attr读取器)返回的值”(当然是
nil
,因为尚未设置该值)


因此,你所有的披头士乐队都没有名字,输出的是Paul和Ringo的嗜好的两个朋友,但是所有的名字都是空的。

顺便说一下,在你的method missing中,你可以考虑:
如果method=~/^all\u with(.*$/
然后是'attr=$1`谢谢你,我喜欢编写“高效”的代码,当然这是更少的代码。我正在学习Ruby,在我了解regex引擎的工作原理之前,我一直在学习Ruby;)顺便说一句,在您的method missing中,您可能会考虑:
如果method=~/^all\u和$/
,然后是`attr=$1`谢谢,我喜欢编写“高效”的代码,当然这是更少的代码。我正在学习Ruby,在我了解regex引擎的工作原理之前,我一直在学习Ruby;)aaahhh:D这就是你在vi中工作两天所得到的。我很抱歉把这个挂起来。在代码检查方面,我们必须将此代码作为RTFC收回。谢谢。这就是你在vi工作两天所得到的。我很抱歉把这个挂起来。在代码检查方面,我们必须将此代码作为RTFC收回。非常感谢。
#!/usr/bin/env ruby1.9

class Person
        PEOPLE = []
        attr_reader :name, :hobbies, :friends

        def initialize(mame)
                @name = name
                @hobbies = []
                @friends = []
                PEOPLE << self
        end

        def has_hobby(hobby)
                @hobbies << hobby
        end

        def has_friend(friend)
                @friends << friend
        end

        def self.method_missing(m,*args)
                method = m.to_s
                if method.start_with?("all_with_")
                        attr = method[9..-1]
                        if self.public_method_defined?(attr)
                                PEOPLE.find_all do |person|
                                        person.send(attr).include?(args[0])
                                end
                        else
                                raise ArgumentError, "Can't find #{attr}"
                        end
                else
                        super
                end
        end
end

j = Person.new("John") 
p = Person.new("Paul") 
g = Person.new("George") 
r = Person.new("Ringo")

j.has_friend(p) 
j.has_friend(g) 
g.has_friend(p) 
r.has_hobby("rings")

Person.all_with_friends(p).each do |person| 
        puts "#{person.name} is friends with #{p.name}"
end 

Person.all_with_hobbies("rings").each do |person|
        puts "#{person.name} is into rings"
end
is friends with 
 is friends with 
 is into rings