0

eval()はメソッドで使用しますinitialize

class ActiveRecord::FakedModel

  def initialize(attributes={})
    attributes = {} if not attributes

    attributes.each do |attr_name, value|
      eval("@#{attr_name}=#{value.inspect}")
    end

    @attributes = attributes
  end
...
end

空白をクリーニングするためのセッターがあります。

class ContactForm < ActiveRecord::FakedModel
  attr_accessor :plz

  def plz=(plz)
    @plz = plz.try(:delete,' ')
  end
...
end

しかし、ハッシュで「plz」を指定すると、このセッターは機能しません。

c=ContactForm.new(:plz=>' 1  3 3 3 ')
=> #<ContactForm:0x1024e3a10 @attributes={:plz=>" 1  3 3 3 "}, @plz=" 1  3 3 3 ">

でセッターを使用することに何か問題がありevalますか?

4

3 に答える 3

3

evalステートメントはsetterメソッドを呼び出しておらず、インスタンス変数を直接設定しています。コンストラクターでセッターを使用する場合は、send:を使用します。

attributes.each do |attr_name, value|
  send "#{attr_name}=", value
end
于 2012-06-15T10:08:07.173 に答える
2

インスタンス変数の設定には、 Object#instance_variable_setメソッドを使用 します。

attributes.each do |attr_name, value|
  self.instance_variable_set("@#{attr_name}", value.inspect)
end
于 2012-06-15T10:06:44.583 に答える
1

メソッドを動的に実行するには、 を使用しますObject#send

class ActiveRecord::FakedModel

  def initialize(attributes={})
    attributes = {} if not attributes

    attributes.each do |attr_name, value|
      send("#{attr_name}=", value)
    end

    @attributes = attributes
  end

end

また、inspect を呼び出して変数の String へのキャストを強制する必要がないという利点もあります。

を使用することもできますObject#instance_variable_setが、この場合はセッター メソッドをバイパスしているため、セッターにキャストなどのカスタム ロジックがある場合、コードは期待どおりに機能しません。

class ActiveRecord::FakedModel

  def initialize(attributes={})
    attributes = {} if not attributes

    attributes.each do |attr_name, value|
      instance_variable_set("@#{attr_name}", value)
    end

    @attributes = attributes
  end

end
于 2012-06-15T10:10:40.880 に答える