Ruby-on-rails Rails 100% newb 问题 - send() 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7895253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:14:46  来源:igfitidea点击:

Rails 100% newb issue - send() method

ruby-on-railsrubysend

提问by Skittles

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.

这是一个使用 Ruby 1.8.7 和 Rails 1.2.3 的 Rails 应用程序。请不要骂我升级,这是客户的环境,所以我没有那种闲暇。

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.

包含它的控制器是 Performance。我一直在搜索谷歌,试图弄清楚“@performer.send(selected_track)”实际上在做什么,但感觉就像在漩涡中划船。

Can someone please help me make better sense out of this?

有人可以帮助我更好地理解这一点吗?

Thanks.

谢谢。

回答by ctcherry

The Ruby implementation for the sendmethod, which is used to send a method message to an object, works like this:

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

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.

这是基础知识,另外一条重要信息是 send 将允许您将消息发送到 PRIVATE 方法,而不仅仅是公共方法。

@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_missingin the Performerclass that is setup to catch that and perform some action.

至于您的特定发送调用将做什么,很可能def method_missingPerformer类中设置了一个来捕获它并执行一些操作。

Hope this helps, good luck!

希望这有帮助,祝你好运!

回答by apneadiving

sendis 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.

send用于将方法(和参数)传递给对象。当您事先不知道方法的名称时,这真的很方便,因为它仅表示为字符串或符号。

Ex: Performer.find(params[:performer_id])is the same as Performer.send(:find, params[:performer_id])

例如:Performer.find(params[:performer_id])Performer.send(:find, params[:performer_id])

Beware here because relying on params when using sendcould be dangerous: what if users pass destroyor delete? It would actually delete your object.

在这里要小心,因为在使用时依赖参数send可能很危险:如果用户通过destroydelete?它实际上会删除您的对象。

回答by Jacob Mattison

The sendmethod is the equivalent of calling the given method on the object. So if the selected_trackvariable has a value of 1234, then @performer.send(selected_track)is the same as @performer.1234. Or, if selected_trackis "a_whiter_shade_of_pale" then it's like calling @performer.a_whiter_shade_of_pale.

send方法相当于在对象上调用给定的方法。因此,如果selected_track变量的值为 1234,则@performer.send(selected_track)@performer.1234. 或者,如果selected_track是“a_whiter_shade_of_pale”,那么就像调用@performer.a_whiter_shade_of_pale.

Presumably, then, the Performer class overrides method_missingsuch 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.

据推测,Performer 类会覆盖method_missing,以便您可以使用任何曲目(名称或 ID,从上面不清楚)调用它,并且它会将其解释为在该表演者的曲目中搜索该曲目。