2016-11-21 5 views
2

インスタンス変数の初期化は、バルクへの簡単な方法は、インスタンス変数にルビー:質量

def initialize(title: nil, label_left: nil, label_right: nil, color_set: nil) 
    @title = title 
    @label_left = label_left 
    @label_right = label_right 
    @color_set = color_set 
    end 

を割り当てるあり、私はループ/初期化引数を反復処理し、自動的に割り当てることができますか?

答えて

9

特定の変数が必要な場合は、実際にはありません。ここで反射を使用すると、それが利用可能であっても、問題になります。

あなたがここにいるのはもっとも簡単なケースです。多くの場合、次のようなコードが表示されます。

def initialize(title: nil, label: nil, label_width: nil, color_set: nil) 
    @title = title.to_s 
    @label = label_left.to_s 
    @label_width = label_width.to_i 
    @color_set = MyRGBConverter.to_rgb(color_set) 
end 

初期化子は、必要な変換と検証ができる場所です。それらの引数のうちのいくつかが特定の値であることが要求される場合は、そのためのテストがあります。raiseはエラーなどの例外です。最小限のケースでここにある繰り返しコードは、拡張されて拡張されることが多く、一般的な解決策はありません。次のようなコードにつながる

def initialize(title: nil, label: nil, label_width: nil, color_set: nil) 
    @title = title.to_s 
    unless (@title.match(/\S/)) 
    raise "Title not specified" 
    end 

    @label = label_left.to_s 
    unless (@label.match(/\A\w+\z/)) 
    raise "Invalid label #{@label.inspect}" 
    end 

    @label_width = label_width.to_i 
    if (@label_width <= 0) 
    raise "Label width must be > 0, #{@label_width} specified." 
    end 

    @color_set = MyRGBConverter.to_rgb(color_set) 
end 

あなたは本当にあなたが取っているどの引数を気にしないならば、あなたは新しいキーワード引数を使ってRubyの2.3でこれを行うことができます指定**:これらの値は、ユーザが供給しているので、あなたがしたい場合があります場合は、潜在的に危険だ

def initialize(**options) 
    options.each do |key, value| 
    instance_variable_set("@#{key}", value) 
    end 
end 

注何とかそれらをホワイトリスト:

VALID_OPTIONS = [ :title, :label_left, :label_right, :color_set ] 

def initialize(**options) 
    options.each do |key, value| 
    raise "Unknown option #{key.inspect}" unless (VALID_OPTIONS.include?(key)) 

    instance_variable_set("@#{key}", value) 
    end 
end 

これらの引数が定期的に渡されるのを見ていると、何らかの構造体のようなオブジェクトを作成し、それを渡す方が良い計画かもしれないかどうか評価したいと思うかもしれません。コードの仕組みによって異なります。

1

@tadmanはすでにこれに対する優れた答えを提供するが、ここでは1以上である。

def initialize(*args) 
    @title, @label_left, @label_right, @color_set, *nada = args 
    fail "Too many arguments" unless nada.empty? 
end 

[UPDATE:固定コード名前付きパラメータを省略して喜んでいる場合は、このようにそれを行うことができます@sawaによって与えられたコメントによると、

+1

「* nada」、「nada.empty」以外に変更して、意図したとおりに動作させる必要があります。 Rubyistsは '*'と書くのが好きです。 – sawa

+0

エラーを指摘してくれてありがとう。私は私の答えでそれを修正します。コメントの後半部分について詳しく説明できますか?この場合、どのようにソール '* 'を使うことができますか? – user1934428

+0

申し訳ありませんが、あなたのように '* nada'が必要です。ところで、空の方法はありません。 – sawa