Rubyプログラミング:明確なコードですか、それとも簡潔で洗練されたコードですか.
1722 ワード
Pier Cawleyは、遅延初期化のプロパティを紹介するブログ記事で発見された潜在的な問題を検討した.問題が発生したコードは次のとおりです.
このコードの目的は、クラスの遅延初期化プロパティをサポートすることです.この例では、
しかし、Piersは、Rubyがブール値と
このようなコードの結果はどうなりますか?
Rubyで
Rubyでは
これは通常の意味では問題にならないが、初期化属性を遅延させるコードでは、属性に付与される正当な値が
もちろん、これは境界状況ですが、このような問題は、デバッグに長い時間を費やし、なぜいくつかの方法がリセットされる場合があり、他の方法が再設定されないのかを見つけようとします.
Piersはこのコードに対してより明確なコードを与えた.
これにより、コードは変数が定義されていない場合にのみ変数を初期化します.
この小さな例では、Rubyとその一部の言語特性のせいにすることができますが、どのプログラマーが彼ら自身ではなくツールのせいにするかはよく知られています.Rubyコードの簡潔さは非常に有用であるが,意図をより明確に表現する式を用いるとより安全になる場合がある.この例では、
親愛なる読者、あなたも以前このような問題に頭を叩かれたことがありますか?Rubyは、上記の発見しにくい問題を予防するために避けたい言語特性がありますか?
原文:Explicit vs.concise code in Ruby
def content
@content ||= []
end
このコードの目的は、クラスの遅延初期化プロパティをサポートすることです.この例では、
@content
というインスタンス変数が初期化されていない限り、そのアクセサメソッドcontent
メソッドが呼び出されると初期化されます.||=
このオペレータは、「左の変数値がnil
の場合、その値を右の式に割り当てます.そうしないと、左の変数値のみが返されます」という意味です.しかし、Piersは、Rubyがブール値と
nil
を処理する方法が特殊であるため、いくつかの値にとって問題が発生すると指摘した.次の例を見てみましょう.a = false
a ||= "Ruby"
このようなコードの結果はどうなりますか?
a
はすでに第1行で初期化されているので、第2行は何の効果も生じてはならない.しかし、コードの実行後、a
の現在の値はfalse
ではなく「Ruby」であることがわかります.Rubyで
nil
を記述して汎用方式をチェックすると、問題は非常に明らかになります.if name
puts name.capitalize
end
Rubyでは
nil
がブール値false
と解釈されるため、if
句のコードはname
の値がnil
に等しくない場合にのみ実行される.これは通常の意味では問題にならないが、初期化属性を遅延させるコードでは、属性に付与される正当な値が
nil
またはfalse
である場合、問題となる.この場合、プロパティにアクセスすると、プロパティ値がデフォルト値にリセットされます.もちろん、これは境界状況ですが、このような問題は、デバッグに長い時間を費やし、なぜいくつかの方法がリセットされる場合があり、他の方法が再設定されないのかを見つけようとします.
Piersはこのコードに対してより明確なコードを与えた.
def content
unless instance_variable_defined? :@content
@content = []
end
return @content
end
これにより、コードは変数が定義されていない場合にのみ変数を初期化します.
この小さな例では、Rubyとその一部の言語特性のせいにすることができますが、どのプログラマーが彼ら自身ではなくツールのせいにするかはよく知られています.Rubyコードの簡潔さは非常に有用であるが,意図をより明確に表現する式を用いるとより安全になる場合がある.この例では、
||=
は正しい解決策ではなく、逆に初期化コードは変数が定義されているかどうかを確認しなければならない.親愛なる読者、あなたも以前このような問題に頭を叩かれたことがありますか?Rubyは、上記の発見しにくい問題を予防するために避けたい言語特性がありますか?
原文:Explicit vs.concise code in Ruby