我不明白send
在以下代码中是如何工作的,因为它没有使用符号。为什么它设法返回属性的值?
以下是代码:
module FormatAttributes
def formats(*attributes)
@format_attributes = 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
resume = Resume.new
resume.name = "Superman"
resume.email = "superman@gmail.com"
resume.phone_number = "12345"
resume.experience = "Ruby"
resume.display
结果是:
[NAME] Superman
[PHONE_NUMBER] 12345
[EMAIL] superman@gmail.com
[EXPERIENCE] Ruby
答案 0 :(得分:0)
您将attribute
变量作为参数传递,该变量可能包含Symbol
或String
个对象。
答案 1 :(得分:0)
self.class.format_attributes
访问者将在类对象上获取@format_attributes
,该对象已由[:name, :phone_number, :email, :experience]
行设置为formats
。
当您对attribute
进行迭代时,它会获得值:name
,然后是:phone_number
等。
因此,在each
循环内,您将执行send(:name)
,send(:phone_number)
等。
当attribute
在第一次迭代中的值:name
时,send(attribute)
将与send(:name)
执行相同的操作,与name
的操作相同,"Superman"
将返回{{1}}。
答案 2 :(得分:0)
请阅读send
方法的文档。它说:
调用symbol标识的方法,并将指定的参数传递给它。如果名称发送与obj中的现有方法发生冲突,则可以使用发送。当方法由字符串标识时,字符串将转换为符号。
现在,您已在Formatter
课程中添加extend
模块并使用FormatAttributes
Resume
模块。毋庸置疑,它实际上使display
方法来自Formatter
实例方法。此外,来自formats
的{{1}}和format_attributes
将作为FormatAttributes
类的类方法提供。现在,您的显示方法:
Resume
调用 def display
self.class.format_attributes.each do |attribute|
puts "[#{attribute.to_s.upcase}] #{send(attribute)}"
end
end
,这是format_attributes
方法,因此你执行:class
,因为这个方法假设返回一个属性数组,它们作为符号传递:
self.class.format_attributes
因此:
formats :name, :phone_number, :email, :experience
现在@format_attributes = [:name, :phone_number, :email, :experience]
阻止了each
,你有:
attribute
对于一个实例,可以翻译为:
puts "[#{attribute.to_s.upcase}] #{send(attribute)}"
因此,puts "[#{:name.to_s.upcase}] #{send(:name)}"
将在name
类的实例方法上调用,这就是你看到所有输出的原因。
编辑:为什么Resume
,:name
,:phone_number
和:email
可用作方法?
这是因为这一行:
:experience
详细了解attr_accessor
here。