instance_variable_set, instance_variable_getでレシーバのインスタンス変数を設定・取得

Ruby の instance_variable_set, instance_variable_get を使ったので忘れないようにまとめときます。Rails でユーザーのタイムゾーン管理絡みで使ったのですが、Rails で多言語・他地域のローカライズを行う場合、タイムゾーンの管理を以下の方針としています。

Rails でのタイムゾーン管理の方針 | EasyRamble

簡単に言うと、DB 内では全て UTC に統一して時刻を保存する方針。そして、時刻を出力する際に in_time_zone メソッドで、ユーザーのタイムゾーンに合わせて時刻を変換する。

スポンサーリンク

instance_variable_set でレシーバにインスタンス変数の値を設定

上記方針でタイムゾーンを管理していたのですけど、一時的にユーザーのタイムゾーンに合わせて変換した時刻を、レシーバのオブジェクトに保持させたいケースに遭遇しました。ここで、レシーバにインスタンス変数の値を設定する instance_variable_set を使った。以下、pry での例です。

“user has_many posts” という関係のモデルで、user の最初の post オブジェクト(first_post)に、タイムゾーン変換後の時刻のインスタンス変数の値を instance_variable_set で設定します。first_post が作成されたタイムゾーン変換後の時刻として、@created_at_utz というインスタンス変数の値を設定している。

これで、first_post に @created_at_utz というインスタンス変数の値が設定されました。

instance_variable_get でレシーバのインスタンス変数を取得

first_post の UTC 時刻。普通にモデルの属性にアクセスすれば良い。

first_post のタイムゾーン変換後の時刻(Tokyo/JST)を取得するには、instance_variable_get で先ほど設定した @created_at_utz インスタンス変数の値を取得できます。

一応これでやりたいことは実現できたのですけど、まだ良い方法がある気がするので、メタプログラミングRubyを読みなおそう。メタプログラミングRubyは、あと10回くらい読み直さないといけませんね。

スポンサーリンク
私は以下の本で Ruby を覚えました。メタプログラミングRubyは入門を超える内容で難しめです。
スポンサーリンク
 
Twitterを使っていますのでフォローお願いたします!ブログの更新情報もつぶやいてます^^
(英語学習用)

Leave Your Message!