我知道在Ruby中,与其他语言不同,有类方法继承。
class A
def self.filter_by
"filter"
end
end
class B < A
end
B.filter_by => "filter"
B的单例类从A的单例类继承方法,它似乎继承了这些类方法的实例变量:
class A
class << self
attr_accessor :filter_by
end
end
class B < A
end
B.filter_by = "filter"
A.filter_by = "no_filter"
=> "no_filter"
B.filter_by # B's value is not changed
=> "filter"
但它没有继承值:
class A
class << self
attr_accessor :filter_by
end
end
class B < A
end
A.filter_by = "filter"
B.filter_by => nil
B没有继承设置为A的@filter_by实例变量的值。
可以使用内置的继承钩子以this方式解析,或者在Rails中使用class_attribute
:
class A < ActiveRecord::Base
class_attribute :filter_by
end
class B < A
end
A.filter_by = "filter"
=> "filter"
B.filter_by # Now B's @filter_by inherited the value set in A's @filter_by
=> "filter"
但我不明白为什么我不能这样做:
class A < ActiveRecord::Base
class_attribute :filter_by
end
class B < A
filter_by= %w(user_id_is status_id_is task_category_id_is)
end
B.filter_by => nil
为什么在这种情况下它返回nil而在其他情况下不返回?在这种情况下,当我声明B(它是单例对象)时,我在self上设置了一个值。
答案 0 :(得分:3)
请记住,在上一个示例中,有
filter_by
的类属性(包含相应的filter_by
和filter_by=
方法(继承自A类)filter_by
。变量filter_by
在范围之外不可用,并且在任何类型的class B
方法中也不可用。在class B
中,您已将此变量设置为字符串列表,但是当您执行B.filter_by
时,将调用从class A
继承的方法。此值尚未设置,因此会返回nil
。
如果您在课程中完成了self.filter_by = %w(...)
,那么它就会访问方法filter_by=
并按照您的意图设置class属性。
答案 1 :(得分:2)
您在分配属性时忘记了self.
。 Ruby认为你分配给了一个本地人。使用self.
:
class A < ActiveRecord::Base
class_attribute :filter_by
end
class B < A
self.filter_by= %w(user_id_is status_id_is task_category_id_is)
end
B.filter_by => nil
=> ["user_id_is", "status_id_is", "task_category_id_is"]