【问题标题】:Ruby's send method with block variable interpolation带有块变量插值的 Ruby 发送方法
【发布时间】:2013-03-24 01:24:31
【问题描述】:

我是一名新手,正在学习一些 Ruby 教程,并且对使用下面的 send 方法感到困惑。我可以看到 send 方法正在读取属性迭代器的值,但是 Ruby 文档指出 send 方法采用一个以冒号开头的方法。所以,我的困惑在于 下面的 send 方法是如何插入被迭代的属性变量的。

module FormatAttributes
  def formats(*attributes)
    @format_attribute = attributes
  end

  def format_attributes
    @format_attributes
  end
end

module Formatter
  def display
    self.class.format_attributes.each do |attribute|
      puts "[#{attribute.to_s.upcase}] #{send(attribute)}"
    end
  end
end

class Resume
  extend FormatAttributes
  include Formatter
  attr_accessor :name, :phone_number, :email, :experience
  formats :name, :phone_number, :email, :experience
end

【问题讨论】:

  • send 也可以接受字符串,而不仅仅是符号。 “以冒号开头的方法” - 这是一个符号,它是非常基本的 ruby​​ 概念。那么,您的问题到底是什么?
  • 如何将#{send(attribute)} 插入到单个属性值中?
  • attribute 是属性名称,send(attribute) 按名称获取值,#{send(attribute)} 将其插入字符串。这与 #{foo}#{10 * 20} 没有什么不同。

标签: ruby send interpolation


【解决方案1】:

send Documentation

这里是你的代码的简化版本,告诉你发生了什么:

def show
 p "hi"
end

x = "show"
y = :show

"#{send(y)}"   #=> "hi"
"#{send(x)}"   #=> "hi"

【讨论】:

  • 值得注意的是x = :show; "#{send(x)}" 也可以。我认为在这种情况下,字符串值被强制转换为符号,因此对 OP 的部分答案可能是“Ruby 提供内置强制,并且允许发布的代码工作”
  • @NeilSlater 我试图向他展示 send 的工作原理。而已。我的代码有什么问题吗?纠正我。我没听懂你。
  • 您的代码没有问题。我只是想把它加入我在 OP 中注意到的东西(“采用一个以冒号开头的方法”)
【解决方案2】:

这不是“调用迭代器的值”,而是调用具有该名称的方法。在这种情况下,由于 attr_accessor 声明,这些方法映射到属性。

调用object.send('method_name')object.send(:method_name) 等价于一般意义上的object.method_name。同样,send(:foo)foo 将在上下文中调用方法 foo

由于module 声明了一个后来与include 混合的方法,因此在模块中调用send 具有调用Resume 类实例上的方法的效果。

【讨论】:

  • @tadam,谢谢!作为新手,我没有考虑 attr_accessor 正在将属性转换为方法。现在很有意义。
  • attr_reader 创建一个读方法(getter),attr_writer 创建一个写方法(setter),attr_accessor 创建两者。
猜你喜欢
  • 2019-04-05
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
相关资源
最近更新 更多