我的理解是SELECT capital, name FROM world WHERE capital LIKE CONCAT('%', name, '%');
意味着对一个实例是私有的。使用显式接收器无法调用私有方法,甚至private
。要调用私有方法,我必须完成以下过程:
self
这将调用私有class Sample
def foo
baz
end
private
def baz
end
end
Sample.new.foo
方法。有没有办法用显式接收器直接调用私有方法?
答案 0 :(得分:19)
是的,这可以通过Kernel#send
:
receiver.send :method_name, parameters
虽然有BasicObject#instance_eval
或Kernel#binding
操作等变通方法,但调用私有方法的常用方法是在接收方上调用send
。
答案 1 :(得分:2)
使用BasicObject#instance_eval
,您可以调用私有方法。
class Sample
private
def baz
'baz called'
end
end
Sample.new.instance_eval('baz')
# => 'baz called'
Sample.new.instance_eval { baz }
# => 'baz called'
答案 2 :(得分:1)
如其他答案所示,您可以使用send
来调用私有方法。但是,这可能会产生一些不整洁的代码。
如果您确实需要在类的实例上公开访问您的方法,则可以重置方法的可见性。假设您的代码中未定义类,只需重新打开它并设置方法的可见性:
class Sample
public :baz
end
现在你可以打电话给它:
s = Sample.new
s.baz
# => 'baz called'
答案 3 :(得分:1)
您可以在两个级别上回答您的问题:基本语言级别和反思元级别。
在基础语言层面,如果您只是将隐私的定义与您的问题进行对比,答案就显而易见了:
私有方法只能在没有显式接收器的情况下调用
和
我可以在没有明确接收者的情况下呼叫私人吗?
答案显然是“不”,两句话直接相互矛盾。
然而,在反思元层面,答案是“是”。实际上,您可以在元级别上执行几乎任何操作,并绕过几乎任何类型的访问限制,保护,隐藏和封装。
var haystack="UGDVWUDDPRQLUZMSZOJPSIKAIHLTONYXAULECXXKWFQOIKELWOHRVRUCXIAASKHMWTMAJEWGEESLWRTQKVHRRCDYXNTLDSUPXMQTQDFAQAPYBGXPOLOCLFQNGNKPKOBHZWHRXAWAWJKMTJSLDLNHMUGVVOPSAMRUJEYUOBPFNEHPZZCLPNZKWMTCXERPZRFKSXVEZTYCXFRHRGEITWHRRYPWSVAYBUHCERJXDCYAVICPTNBGIODLYLMEYLISEYNXNMCDPJJRCTLYNFMJZQNCLAGHUDVLYIGASGXSZYPZKLAWQUDVNTWGFFYFFSMQWUNUPZRJMTHACFELGHDZEJWFDWVPYOZEVEJKQWHQAHOCIYWGVLPSHFESCGEUCJGYLGDWPIWIDWZZXRUFXERABQJOXZALQOCSAYBRHXQQGUDADYSORTYZQPWGMBLNAQOFODSNXSZFURUNPMZGHTAJUJROIGMRKIZHSFUSKIZJJTLGOEEPBMIXISDHOAIFNFEKKSLEXSJLSGLCYYFEQBKIZZTQQXBQZAPXAAIFQEIXELQEZGFEPCKFPGXULLAHXTSRXDEMKFKABUTAABSLNQBNMXNEPODPGAORYJXCHCGKECLJVRBPRLHORREEIZOBSHDSCETTTNFTSMQPQIJBLKNZDMXOTRBNMTKHHCZQQMSLOAXJQKRHDGZVGITHYGVDXRTVBJEAHYBYRYKJAVXPOKHFFMEPHAGFOOPFNKQAUGYLVPWUJUPCUGGIXGR";
var needle="ABCD";
var size=haystack.length;
var candidate_substring="";
var minimal_length=size;
var solutions=new Array();
var points=Array();
for(var i=0;i<size;i++){
if(needle.indexOf(haystack[i])>-1) points.push(i);
}
var limit_i= points.length-4;
var limit_k= points.length;
for (var i=0;i<limit_i;i++){
for(var k=i;k<limit_k;k++){
if(points[k]-points[i]+1<=minimal_length){
candidate_substring=haystack.substr(points[i],points[k]-points[i]+1);
if(is_valid(candidate_substring)){
solutions.push(candidate_substring);
if(candidate_substring.length < minimal_length) minimal_length=candidate_substring.length;
}
}
}
}
document.write('<p>Solution length:'+minimal_length+'<p>');
for(var i=0;i<solutions.length;i++){
if(solutions[i].length<=minimal_length) document.write('<p>Solution:'+solutions[i]+'<p>');
}
function is_valid(candidate_substring){
//verify we've got all characters
for(var j=0;j<candidate_substring.length;j++){
if(candidate_substring.indexOf(needle.charAt(j))<0) return false;
}
//...and verify we have two "A"
if(candidate_substring.indexOf("A")==candidate_substring.lastIndexOf("A")) return false;
return true;
}
,其主要目的是允许您调用一个在运行时之前不知道其名称的方法,还具有绕过访问限制的额外副作用,例如Object#send
和{{ 1}}。 (它也忽略了Refinements,这是你应该注意的重要限制!)