'What is the send() method used for?
Could someone please help me to understand what the 'send()' method listed below is used for? The code below, when I am reading it, makes no sense what purpose it's serving.
It's a Rails app using Ruby 1.8.7 with Rails 1.2.3. Please don't harp on me about upgrading, it's a client's environment, so I don't have that sort of leisure.
Needless to say though, the statement I am referring to is like this;
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
Performer Model
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
The controller that this is contained in is Performance. I have been scouring Google trying to figure out what purpose that '@performer.send(selected_track)' is actually doing, but feel like I'm rowing against a whirlpool.
Solution 1:[1]
The Ruby implementation for the send
method, which is used to send a method message to an object, works like this:
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
That's the basics, an additional piece of important information is that send will allow you you send in messages to PRIVATE methods, not just public ones.
@car.engine_temp # This doesn't work, it will raise an exception
@car.send(:engine_temp) # output: Just Right
As for what your specific send call will do, more than likely there is a def method_missing
in the Performer
class that is setup to catch that and perform some action.
Solution 2:[2]
send
is used to pass a method (and arguments) to an object. It's really handy when you don't know in advance the name of the method, because it's represented as a mere string or symbol.
Ex: Performer.find(params[:performer_id])
is the same as Performer.send(:find, params[:performer_id])
Beware here because relying on params when using send
could be dangerous: what if users pass destroy
or delete
? It would actually delete your object.
Solution 3:[3]
The send
method is the equivalent of calling the given method on the object. So if the selected_track
variable has a value of 1234, then @performer.send(selected_track)
is the same as @performer.1234
. Or, if selected_track
is "a_whiter_shade_of_pale" then it's like calling @performer.a_whiter_shade_of_pale
.
Presumably, then, the Performer class overrides method_missing
such that you can call it with any track (name or ID, it isn't clear from the above), and it will interpret that as a search for that track within that performer's tracks.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dharman |
Solution 2 | apneadiving |
Solution 3 | Jacob Mattison |