有人可以帮我理解下面列出的'send()'方法用于什么?下面的代码,当我阅读它时,没有任何意义,它的目的是什么。
这是一个使用Ruby 1.8.7和Rails 1.2.3的Rails应用程序。请不要对我进行升级改造,这是客户的环境,所以我没有那种闲暇。
不用说,我所指的陈述是这样的;
def do_schedule
@performance = Performance.new(params[:performance])
@performer = Performer.find(params[:performer_id])
selected_track = params[:selected_track]
if FileTest.exists?(File.expand_path(@performer.photo))
@performance.photo = File.open(File.expand_path(@performer.photo))
end
@performance.audio = File.open(File.expand_path(@performer.send(selected_track)))
if @performance.save
flash[:notice] = 'Performer scheduled.'
redirect_to :controller => :performer, :action => :index
else
render :action => 'schedule'
end
end
表演者模特
class Performer < ActiveRecord::Base
file_column :audio_one
file_column :audio_two
file_column :audio_three
file_column :photo
belongs_to :festival
validates_presence_of :name, :first_name, :last_name, :address, :city, :state, :zip, :daytime_phone, :availability, :stages
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
validates_confirmation_of :email
validates_presence_of :audio_one, :audio_two, :audio_three, :photo, :if => :submitted
after_create :salt_access_key
serialize :availability
serialize :stages
attr_accessor :other_type_of_music
before_save :set_other_type
def set_other_type
if type_of_music == 'Other'
self.type_of_music = "Other - #{other_type_of_music}" unless other_type_of_music.blank?
end
end
def salt_access_key
update_attribute(:access_key, Digest::SHA1.hexdigest("--#{self.id}--#{self.name}--#{self.festival.year}"))
end
def preferred_stages
stages = []
festival = Festival.find(self.festival_id.to_i)
self.stages.collect { | key, value |
id = key.gsub(/[\D]/, '').to_i
if id > 0
stages << festival.performance_stages.find(id).name
end
}
return stages
end
end
包含它的控制器是Performance。我一直在搜索谷歌试图找出'@performer.send(selected_track)'实际上在做什么的目的,但感觉我正在对抗一个漩涡。
有人可以帮助我更好地理解这个吗?
感谢。
答案 0 :(得分:65)
send
方法的Ruby实现,用于向对象发送方法消息,其工作方式如下:
class Car
def start
puts "vroom"
end
private
def engine_temp
puts "Just Right"
end
end
@car = Car.new
@car.start # output: vroom
@car.send(:start) # output: vroom
这是基础知识,另外一条重要信息是发送将允许您向PRIVATE方法发送消息,而不仅仅是公共方法。
@car.engine_temp # This doesn't work, it will raise an exception
@car.send(:engine_temp) # output: Just Right
至于您的特定发送调用将执行的操作,def method_missing
类中的Performer
很可能会设置为捕获该操作并执行某些操作。
希望这有帮助,祝你好运!
答案 1 :(得分:12)
send
用于将方法(和参数)传递给对象。当你事先不知道方法的名称时它非常方便,因为它只表示为字符串或符号。
例如:Performer.find(params[:performer_id])
与Performer.send(:find, params[:performer_id])
请注意,因为在使用send
时依赖params可能会很危险:如果用户通过destroy
或delete
会怎样?它实际上会删除你的对象。
答案 2 :(得分:6)
send
方法相当于在对象上调用给定方法。因此,如果selected_track
变量的值为1234,则@performer.send(selected_track)
与@performer.1234
相同。或者,如果selected_track
是“a_whiter_shade_of_pale”,那么就像调用@performer.a_whiter_shade_of_pale
一样。
然后,Performer类会覆盖method_missing
,以便您可以使用任何轨道(名称或ID,从上面不清楚)调用它,并且它会将其解释为搜索跟踪表演者的曲目。