红宝石中的& method(:method_ name)`是什么意思? [英] What does `&method(:method_ name)` mean in ruby?

查看:135
本文介绍了红宝石中的& method(:method_ name)`是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个具有私有类方法的类.我希望可以在实例方法中使用此私有类方法.

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_greeterAnimal.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

这篇关于红宝石中的&amp; method(:method_ name)`是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆