所以,我一直在玩一些模型,并且遇到了一种情况,我真的很想限制子类对类方法的继承。麻烦的是,到目前为止,我的实验已经证实了我的理解,这是无法做到的。
我天真地尝试了以下方法:
class Policy
class << self
def lookup(object)
#returns a subclass by analyzing the given object, following a naming convention
end
def inherited( sub )
sub.class_eval { remove_method :lookup }
end
end
end
当然这不起作用,因为子类没有方法,它在超类上。之后我尝试了:
def inherited( sub )
class << Policy
remove_method :lookup
end
end
这就像一个魅力,哈哈,除了它在第一次加载子类时通过从超类中删除方法来工作的微小细节。哎呀!
因此,由于 Ruby 查找方法的方式,我很确定这是行不通的。
我感兴趣的原因是,在我正在处理的行为中,您可能有许多不同的策略,遵循命名约定,我希望有一种干净的方式来获取对任何其他类的策略的引用的对象。对我来说,从语法上讲,这样做似乎很好:
class RecordPolicy < Policy
# sets policy concerning records,
# inherits common policy behavior from Policy
end
class Record
end
$> record = Record.new
=> #<Record:0x0000>
$> Policy.lookup(record)
=> RecordPolicy
但是,我认为能够调用RecordPolicy#lookup
. 你有政策,下面没有什么可以找到的。
所以,我的问题是两个部分:
1)事实上,是否有某种方法可以选择性地定义在 Ruby 中可以继承哪些类方法?
在这一点上,我几乎可以肯定答案是否定的,因此:
2) 鉴于我想封装用于在某处为任何给定对象推断策略名称的逻辑,并且在我看来,到目前为止我所尝试的方法表明 Policy 类是错误的地方,你会把它放在哪里这种东西呢?
谢谢!
更新
感谢 JimLim 对第 1 部分的回答,以及 Linuxios 对第 2 部分的回答。两者都非常有用。
FWIW,在反思了 Linuxios 所说的之后,这就是我决定做的事情:
class << self
def lookup( record )
if self.superclass == Policy
raise "No default naming convention exists for subclasses of Policy. Override self.lookup if you want to use it in a subclass."
else
# naming convention lookup goes here
end
end
end
我觉得对于如何使用此代码来说,这是最不令人惊讶的事情。如果有人出于某种原因在子类上提供#lookup 方法,他们可以设置一个,但如果他们调用继承的方法,他们会得到一个异常,告诉他们这样做没有意义。
至于如何决定谁得到“答案”,因为他们都回答了我问题的 1/2,我个人在“平局”的情况下的习惯是接受当时声誉较低的人的答案。
谢谢你们的帮助!