Rubyの初期化メソッドで複数のインスタンス変数に同じ値を割り当てるにはどうすればよいですか? 以下のリファクタリングを検討しています。
def initialize
@weekly_stats = Hash.new {|h, k| h[k]={}}
@report_times = Hash.new {|h, k| h[k]={}}
@email_stats = Hash.new {|h, k| h[k]={}}
end
Rubyの初期化メソッドで複数のインスタンス変数に同じ値を割り当てるにはどうすればよいですか? 以下のリファクタリングを検討しています。
def initialize
@weekly_stats = Hash.new {|h, k| h[k]={}}
@report_times = Hash.new {|h, k| h[k]={}}
@email_stats = Hash.new {|h, k| h[k]={}}
end
Not sure what doing this in a one-liner buys you but you could do something like this:
%w{weekly_stats report_times email_stats}.each { |v| instance_variable_set("@#{v}", Hash.new {|h, k| h[k]={}} }
Or break it into two non-duplicating lines like:
vars = %w{weekly_stats report_times email_stats}
vars.each { |v| instance_variable_set("@#{v}", Hash.new {|h, k| h[k]={}} }
Or combining it with jvnill's answer:
value = Hash.new {|h, k| h[k]={}}
vars = %w{weekly_stats report_times email_stats}
vars.each { |v| instance_variable_set("@#{v}", value.dup }
ハッシュを割り当てているため、これを 1 行で行うことはできません。Vinayの答えを使用する
>> a = b = c = { a: 'b', c: 'd' }
>> a # {:a=>"b", :c=>"d"}
>> a[:a] = 2 # 2
>> b # {:a=>2, :c=>"d"}
上記の例では、 をb
変更したときに変更されましa
た。これを1行で書く方法があるかどうかはわかりませんが、代わりに次のコードを試してください
@weekly_stats = Hash.new {|h, k| h[k]={}}
@report_times = @weekly_stats.dup
@email_stats = @weekly_stats.dup
これを試して、
@weekly_stats = @report_times = @email_stats = Hash.new {|h, k| h[k]={}}
これは機能しますが、Ruby では不変である数値の変数を使用している場合にのみ、状況に対して安全であることを知っておく必要があります。たとえば、文字列で同じことを試みた場合、予期しない動作が発生する可能性があります。
ruby-1.9.2-p180 :001 > foo = bar = "string"
=> "string"
ruby-1.9.2-p180 :002 > foo.upcase!
=> "STRING"
ruby-1.9.2-p180 :003 > bar
=> "STRING"