Rubyプログラミングにおけるアサインメント関連操作
古いバージョンのRubyでは、代入文の返り値は、プロパティを設定したメソッドの返り値でした。Ruby 1.8では、代入文の値は常に引数の値で、メソッドの戻り値は破棄されます。
class Test
def val=(val)
@val = val
return 99
end
end
t = Test.new
a = t.val=2
a ->2
古いバージョンでは、aは代入文によって99に設定されていましたが、Ruby 1.8では2という値を持っています。
Rubyの代入は実際には並列に実行されるので、代入文の右辺の値は代入文自体の影響を受けません。左側の変数やプロパティが代入される前に、右側の値が現れる順番に計算されます。次の人間が設計した例では、この点を説明しています。2行目は、式 x ,x+=1, x+=1 の値をそれぞれ変数 a, b, c に代入することについて述べています。
x = 0 -> 0
a,b,c =x,(x+=1),(x+=1) ->[0,1,2]
代入文が複数の左値を持つ場合、代入式は右値の配列を返します。代入文が右の値より左の値の方が多い場合、余分な左の値は無視されます。もし、左の値より右の値の方が多い場合は、余分な右の値は無視されます。代入文の左値が1つだけで、右値が複数ある場合、右値は配列に変換された後、左値に代入される。
実は、書き込み可能な属性には、隠れた罠があるのです。通常、あるクラスのメソッドは、同じクラスやその親クラスの他のメソッドを関数として(つまり、暗黙のselfを受け手として)呼び出すことができます。しかし、これはプロパティの割り当て関数には適用されません。Ruby は代入文を見て、左側の名前はローカル変数であり、プロパティに値を代入するメソッド呼び出しではないと判断します。
class BrokenAmplifier
attr_accessor :left_channel, :right_channel
def volume=(vol)
left_channel = self.right_channel = vol
end
end
ba = BrokenAmplifier.new
ba.left_channel = ba.right_channel = 99
ba.volume = 5
ba.left_channel ->99
ba.right_channel ->5
上の代入文では、left_channel の前に "self." を付けるのを忘れたため、Ruby はオブジェクトのプロパティを全く更新しないので、volume= メソッドのローカル変数に新しい値が格納されます。これは追跡困難な不具合になりかねません
関連
-
基本的なユーザー登録とログイン機能を実装するためのRuby on Railsチュートリアル
-
Rubyにおけるフックメソッドとメソッド呼び出しへのフックの追加例
-
RubyとRuby on Railsフレームワーク環境構築の簡潔なチュートリアル
-
Rubyのオブジェクト指向プログラミングにおけるスコープの簡単な説明
-
Nokogiriパッケージを使ってXML形式のデータを操作するためのRubyチュートリアル
-
Rubyのデザインパターン開発におけるProxyパターンの利用について
-
RubyアプリケーションでHTTPベースのリクエストを送信する簡単な例
-
Rubyメタプログラミングの注目すべき点
-
ブログのスパムメッセージを簡単にブロックする方法
-
Rubyにおけるrequireの使用例
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
RVMを使ってRuby/Railsのバージョン切り替えを制御する
-
画像フィルターアルゴリズムコードのRuby実装
-
挿入ソートアルゴリズムのRuby実装と高度な双方向挿入ソートコード例
-
MongoDBに接続するためのRuby on Railsフレームワークアプリケーション チュートリアル
-
Rubyのシングルトンメソッドとシングルトンクラス
-
Ruby on RailsでPing ++プラットフォームでの決済を実現
-
Rubyの4つの比較関数(equal?, eql?, ==, ===)について解説します。
-
Ruby on Railsのパフォーマンスを最適化するためのいくつかの方法についての考察
-
RubyインタプリタをOSにインストールするためのチュートリアル
-
Ruby on RailsでMarkdownを使用する方法