gpt4 book ai didi

ruby - 一元运算符和在 Ruby 中将 proc 作为参数传递

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

我无法理解下面这段代码。

我想到了一元与号运算符并将 proc 作为参数传递给方法。但我真的无法将 self 传递给 language.call。我是这样理解的:我们将 self 作为参数传递给 proc/block 语言。这对我来说没有任何意义。有人可以解释一下吗? :)

class Translator    
def speak &language
language.call(self)
end

protected

def french
'bon jour'
end

def spanish
'hola'
end

def turkey
'gobble'
end

def method_missing(*args)
'awkward silence'
end
end

我们将它用于:

translator.speak(&:spanish)

最佳答案

此示例将多个 Ruby 概念完美地结合在一起。因此,我将尝试解释所有这些。

  1. 积木

Ruby 中的方法可以优雅地接受 block (代码片段):

def run_code
yield
end

run_code { puts 42 } # => prints 42
  1. Procs 类似于 block ,但它们是实际可寻址的对象:
deep_thought = proc { puts 42 }
deep_thought.call # => prints 42
  1. 在使用 & 运算符调用方法时,您可以将 proc 变成 block :
def run_code
yield
end

deep_thought = proc { puts 42 }
run_code(&deep_thought) # => prints 42
  1. 过程和 block 可以接受参数:
def reveal_answer
yield 5_000
end

deep_thought = proc do |years_elapsed|
years_elapsed >= 7_500_000 ? 42 : 'Still processing'
end

reveal_answer(&deep_thought) # => 'Still processing'
  1. 您可以在方法签名中使用 & 将 block 转换为 proc:
def inspector(&block)
puts block.is_a?(Proc)
puts block.call
end

inspector { puts 42 } # => prints true and 42
inspector(&proc { puts 42 }) # => the same
  1. Symbol#to_proc 创建一个调用对象上同名方法的过程:
class Dummy
def talk
'wooooot'
end
end

:talk.to_proc.call(Dummy.new) # => "wooooot"

换句话说,

:bar.to_proc.call(foo)

几乎等同于

foo.bar
  1. BasicObject#method_missing:

当您尝试调用一个对象的方法时,Ruby 会遍历它的祖先链,搜索具有该名称的方法。如何构建链是一个不同的主题,足够长的一天了,重要的是如果直到最底部(BasicObject)都没有找到该方法,则对相同的对象执行第二次搜索chain - 这次是一个名为 method_missing 的方法。它作为参数传递原始方法的名称加上它收到的任何参数:

class MindlessParrot
def method_missing(method_name, *args)
"You caldt #{method_name} with #{args} on me, argh!"
end
end

MindlessParrot.new.foo # => "You caldt foo with [] on me, argh!"
MindlessParrot.new.bar :baz, 42 # => "You caldt bar with [:baz, 42] on me, argh!"

那么在我们的具体情况下,这一切意味着什么呢?让我们暂时假设没有protected


translator.speak(&:spanish)

调用方法 Translator#speak 并将 :spanish 转换为 block 。


Translator#speak 获取该 block 并将其转换为名为 language 的过程,并调用它,将 self 作为参数传递。


selfTranslator 的实例,因此,它具有方法 speakfrenchspanishturkeymethod_missing


所以:

Translator.new.speak(&:spanish)

相当于:

:spanish.to_proc.call(Translator.new)

相当于:

Translator.new.spanish

给我们“hola”


现在,把protected拿回来,我们的translator对象的所有语言方法都还在,只是不能被外人直接访问。


就像你不能打电话一样

Translator.new.spanish

期待“hola”回来,你不能打电话

Translator.new.speak(&:spanish)




由于无法直接访问该方法,因此将其视为未找到并调用 method_missing,从而给我们 “尴尬的沉默”

关于ruby - 一元运算符和在 Ruby 中将 proc 作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37056892/

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