红宝石中的& method(:method_ name)`是什么意思? [英] What does `&method(:method_ name)` mean in ruby?
问题描述
我试图创建一个具有私有类方法的类.我希望可以在实例方法中使用此私有类方法.
I was trying to create a class that has a private class method. I want this private class method available to be used inside an instance method.
以下是我的第一次尝试:
The following was my first attempt:
class Animal
class << self
def public_class_greeter(name)
private_class_greeter(name)
end
private
def private_class_greeter(name)
puts "#{name} greets private class method"
end
end
def public_instance_greeter(name)
self.class.private_class_greeter(name)
end
end
Animal.public_class_greeter('John')
正常工作,打印John greets private class method
.
但是,Animal.new.public_instance_greeter("John")
会引发错误:NoMethodError: private method 'private_class_greeter' called for Animal:Class
.
这是预料之中的,因为调用self.class.private_class_greeter
与Animal.private_class_greeter
相同,显然会引发错误.
That is expected, as the invocation self.class.private_class_greeter
is same as Animal.private_class_greeter
, which obviously throws an error.
在研究如何解决此问题后,我想到了下面的代码来完成这项工作:
After searching on how this can be fixed, I came up with the following code, that does the job:
class Animal
class << self
def public_class_greeter(name)
private_class_greeter(name)
end
private
def private_class_greeter(name)
puts "#{name} greets private class method"
end
end
define_method :public_instance_greeter, &method(:private_class_greeter)
end
我不完全了解这里发生的事情:&method(:private_class_greeter)
.
I don't exactly understand what is happening here: &method(:private_class_greeter)
.
您能解释一下这是什么意思吗?
Could you please explain what does this mean?
如果我要更换:
define_method :public_instance_greeter, &method(:private_class_greeter)
具有:
def public_instance_greeter
XYZ
end
那,什么应该代替XYZ
?
推荐答案
Ruby如何解析&method(:private_class_greeter)
?
How does Ruby parse &method(:private_class_greeter)
?
表达式&method(:private_class_greeter)
是
- 方法调用
method(:private_class_greeter)
的值
- 以
&
运算符为前缀.
- the value of the method call
method(:private_class_greeter)
- prefixed with the
&
operator.
method
方法有什么作用?
What does the method
method do?
method
> 方法在当前上下文中查找指定的方法名称,并返回表示该名称的Method
对象. irb
中的示例:
The method
method looks up the specified method name in the current context and returns a Method
object that represents it. Example in irb
:
def foo
"bar"
end
my_method = method(:foo)
#=> #<Method: Object#foo>
一旦有了此方法,就可以使用它进行各种操作:
Once you have this method, you can do various things with it:
my_method.call
#=> "bar"
my_method.source_location # gives you the file and line the method was defined on
#=> ["(irb)", 5]
# etc.
&
运算符的作用是什么?
What is the &
operator for?
&
运算符用于将Proc
作为块传递给方法,该方法希望将一个块传递给该方法.它还会将传入的值隐式调用to_proc
方法,以便将非Proc
的值转换为Proc
.
The &
operator is used to pass a Proc
as a block to a method that expects a block to be passed to it. It also implicitly calls the to_proc
method on the value you pass in, in order to convert values that are not Proc
into a Proc
.
Method
类实现to_proc
—它以Proc
的形式返回方法的内容.因此,您可以为Method
实例加上&
前缀,并将其作为一个块传递给另一个方法:
The Method
class implements to_proc
— it returns the contents of the method as a Proc
. Therefore, you can prefix a Method
instance with &
and pass it as a block to another method:
def call_block
yield
end
call_block &my_method # same as `call_block &my_method.to_proc`
#=> "bar"
define_method
方法只是碰巧占用了一个正在定义的新方法的内容.在您的示例中,&method(:private_class_greeter)
作为块传入现有的private_class_greeter
方法.
The define_method
method just happens to take a block with the contents of the new method that is being defined. In your example, &method(:private_class_greeter)
passes in the existing private_class_greeter
method as a block.
&:symbol
是这样工作的吗?
Is this how &:symbol
works?
是的. Symbol
实现to_proc
,以便您可以简化代码,如下所示:
Yes. Symbol
implements to_proc
so that you can simplify your code like this:
["foo", "bar"].map(&:upcase)
#=> ["FOO", "BAR"]
# this is equivalent to:
["foo", "bar"].map { |item| item.upcase }
# because
:upcase.to_proc
# returns this proc:
Proc { |val| val.send(:upcase) }
如何复制&method(:private_class_greeter)
?
How can I replicate &method(:private_class_greeter)
?
您可以传入一个调用目标方法的块:
You can pass in a block that calls the target method:
define_method :public_instance_greeter do |name|
self.class.send(:private_class_greeter, name)
end
当然,那么您就不必使用define_method
,这将产生与他的回答中提到的Eric相同的解决方案. :
Of course, then you don't need to use define_method
anymore, which results in the same solution Eric mentioned in his answer:
def public_instance_greeter(name)
self.class.send(:private_class_greeter, name)
end
这篇关于红宝石中的& method(:method_ name)`是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!