gpt4 book ai didi

ruby - `&method(:method_ name)` 在 ruby 中是什么意思?

转载 作者:数据小太阳 更新时间:2023-10-29 07:22:20 25 4
gpt4 key购买 nike

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

以下是我的第一次尝试:

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 相同,这显然会引发错误。

在搜索了如何解决这个问题之后,我想到了以下代码,它可以完成这项工作:

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)

你能解释一下这是什么意思吗?

如果我要替换:

define_method :public_instance_greeter, &method(:private_class_greeter)

与:

def public_instance_greeter
XYZ
end

那么,XYZ的内容应该是什么?

最佳答案

Ruby如何解析&method(:private_class_greeter)

表达式&method(:private_class_greeter)

  • 方法调用method(:private_class_greeter)的值
  • & 运算符为前缀。

method 方法有什么作用?

method method 在当前上下文中查找指定的方法名称并返回表示它的 Method 对象。 irb 中的示例:

def foo
"bar"
end

my_method = method(:foo)
#=> #<Method: Object#foo>

一旦你有了这个方法,你就可以用它做各种事情:

my_method.call
#=> "bar"

my_method.source_location # gives you the file and line the method was defined on
#=> ["(irb)", 5]

# etc.

& 运算符有什么用?

& 运算符用于Proc 作为 block 传递给需要 block 的方法传递给它。它还对您传入的值隐式调用 to_proc 方法,以便将不是 Proc 的值转换为 Proc

Method 类实现了 to_proc — 它以 Proc 的形式返回方法的内容。因此,您可以在 Method 实例前加上 & 并将其作为 block 传递给另一个方法:

def call_block
yield
end

call_block &my_method # same as `call_block &my_method.to_proc`
#=> "bar"

define_method 方法恰好采用了一个 block ,其中包含正在定义的新方法的内容。在您的示例中,&method(:private_class_greeter) 将现有的 private_class_greeter 方法作为一个 block 传递。


&:symbol 是这样工作的吗?

是的。 Symbol 实现了 to_proc 以便您可以像这样简化您的代码:

["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)

您可以传入一个调用目标方法的 block :

define_method :public_instance_greeter do |name|
self.class.send(:private_class_greeter, name)
end

当然,这样您就不需要再使用define_method,这将导致Eric 在his answer 中提到的相同解决方案。 :

def public_instance_greeter(name)
self.class.send(:private_class_greeter, name)
end

关于ruby - `&method(:method_ name)` 在 ruby 中是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45013455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com