提问人:oczek.scala 提问时间:4/27/2022 更新时间:4/27/2022 访问量:137
避免从模块调用私有方法
Avoid calling private method from module
问:
有没有可能在模块中制作私有方法? 我想防止从其他模块调用方法。
module A
private
def name # this method can be used in module B
"name"
end
end
module B
def print_name
puts name
end
end
module C
include A
include B
end
class Z
include C
end
Z.new.print_name # want to throw NoMethodError
答:
1赞
Cary Swoveland
4/27/2022
#1
你可以写以下内容。
module A
def name
"name from A"
end
end
module B
def print_name
"name from B"
end
end
module C
include A
include B
def self.included(klass)
B.instance_methods(false).each { |m| klass.send(:private, m) }
end
end
class Z
include C
def test
print_name
end
end
然后
Z.instance_methods.include?(:name)
#=> true
Z.private_instance_methods.include?(:print_name)
#=> true
z = Z.new
#=> #<Z:0x00007fb0f810ad28>
z.name
#=> "name from A"
z.print_name
#=> NoMethodError: private method 'print_name' called for #<Z:0x00007fb0f810ad28>
z.test
#=> "name from B"
请参阅 Module#included。这是几种所谓的“钩子方法”之一。
假设如下。Z
class Z
def print_name
"name from Z"
end
include C
def test
print_name
end
end
然后
z.print_name
#=> NoMethodError: private method 'print_name' called for #<Z:0x00007fb0f810ad28>
z.test
#=> "name from Z"
这表明原来的公共方法已设为私有。注意:Z#print_name
C.ancestors
#=> [Z, C, B, A, Object, Kernel, BasicObject]
评论