32

クラス内にインスタンス変数を動的に作成しました。

class Mine
  attr_accessor :some_var

  def intialize
    @some_var = true
  end

  def my_number num
    self.instance_variable_set "@my_#{num}", num
  end
end

@my_#{num}attr値として今作成するにはどうすればよいですか?

たとえば、これを実行できるようにしたい:

dude = Mine.new
dude.my_number 1
dude.my_1
=> 1
4

7 に答える 7

35

この答えは、クラス空間を汚染しません。たとえば、mine.my_number 4そうすると、の他のインスタンスはメソッドMineを取得しませんmy_4

class Mine
  def my_number num
    singleton_class.class_eval { attr_accessor "my_#{num}" }
    send("my_#{num}=", num)
  end
end

a = Mine.new
b = Mine.new
a.my_number 10 #=> 10
a.my_10 #=> 10
b.my_10 #=> NoMethodError
于 2012-08-07T17:02:51.313 に答える
25

これは、 を使用して実現できます__send__。ここ:

class Mine
  attr_accessor :some_var

  def intialize
    @some_var = true
  end

  def my_number num
    self.class.__send__(:attr_accessor, "my_#{num}")
    self.__send__("my_#{num}=", num)
  end
end

dude = Mine.new
dude.my_number 1
puts dude.my_1

=> 1
于 2011-02-11T00:18:50.700 に答える
10

簡単。my_number メソッド内で属性リーダーを動的に定義できます。

  def my_number num
     self.instance_variable_set "@my_#{num}", num
     self.class.class_eval do
        define_method("my_#{num}") { num }
     end
  end

それがあなたのために働くかどうか見てください

于 2011-02-11T00:20:12.567 に答える
6

OpenStruct を使用することもできます。

require "ostruct"

class Mine < OpenStruct
end

dude = Mine.new
dude.my_number = 1
dude.my_number # => 1

なぜあなたが 1 を返したいのかわかりませんdude.my_1- それはあなたがすでに持っているものをあなたに返してくれませんか?

于 2011-06-07T00:09:17.803 に答える
4

ここで 2 つのメソッドには 1 つの問題があります... インスタンス変数が 1 つのインスタンスに設定されている場合、そのアクセサーはすべてのインスタンスで使用可能になりますself.class

dude = Mine.new
dude.my_number 1
puts dude.my_1
dudette = Mine.new
dudette.my_1 = 2    # works, but probably shouldn't
dudette.my_number 2
dude.my_2 = 3       # works, but probably shouldn't

おそらくやりたいことは、インスタンス変数を持つインスタンスのみを変更することです:

class Mine
  # ...
  def my_number num
    class << self
      attr_accessor "my_#{num}"
    end
    self.send("my_#{num}=", num)
  end
end

このように、インスタンス変数は、作成されたオブジェクトのアクセサーのみを取得します。アクセサーを設定している場合は、それを再利用する方が読みやすいと思うので、instance_variable_setも気にしませんでした。しかし、それはスタイルコールです。ここで重要なのは、class << selfの代わりに呼び出すことですself.class

于 2011-06-06T21:37:57.043 に答える