所以,我一直在使用一些模型,并遇到了这样一种情况:我真的很想通过子类限制继承一个类方法。问题是,我的实验迄今为止证实了我的理解,即这是不可能做到的。
我天真地尝试了以下操作:
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)鉴于我想要封装推断任何给定对象策略名称的逻辑 ,并且我觉得到目前为止我尝试的内容表明策略类是错误的位置,那么您会把这种东西放在哪里呢?
谢谢!
更新
感谢JimLim回答第一部分,Linuxios回答第二部分。两者都提供了非常有用的见解。
顺便说一句,经过思考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方法,他们可以设置一个,但是如果他们调用继承来的那个方法,他们会得到一个异常,告诉他们这样做没有意义。
至于如何决定谁得到“答案”,因为他们都回答了我的问题的一半,我的个人习惯在“平局”情况下是接受那个时间拥有更少声望的人的回答。
感谢你们两位的帮助!
lookup
方法仅仅是用于抛出异常,这样做是个好主意吗? - James Lim