40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

ジョギングしてからRubyの勉強しました

http://farm4.static.flickr.com/3489/3836747792_79ef3f6d98_b.jpg:image:h500:w375
今朝は出社前に心拍150程度で普段のペースからすると若干遅めに走ったら、体のバランスが整って頭もスッキリ!

そのせいか普段よりも集中出来きそれを維持したままRubyの勉強をしました。

ここ1週間ほどはこのページに記載されているプログラムの勉強に良質なコードを読むための参考情報が自分にとっては役に立つ内容だったので、Rubyの標準ライブラリのWEBrickのソースを読みつつ写経して頭の中でコードの動きを追っていたのですが、今日はちょっと気分転換してWEB+DB Pressの49号の「現場で役立つDRYの基礎知識」の特集記事のソースを読む事にしました。

記事に出ていた内容というのは、良く似たメソッドをもった別々のクラスに関してDSLを用いて似たようなメソッド定義を一掃して記述を完結にするというもので、変更後のソースで数カ所自分にとって理解が難しい記述だったので自分の理解した内容を将来の自分のためにメモ。

class ModelObject
  def self.has_image(name, attr=:id, has_icon=true)
    klass = self
    path = "/img/#{klass.name.downcase}/#{name}"
    klass.class_eval <<-END, __FILE__, __LINE__ + 1
      def #{name}_path
        "#{path}/\#{self.#{attr}}.jpg"
      end
      def icon_path
        "#{path}/\#{self.#{attr}}_icon.jpg"
      end if #{has_icon}
    END
  end
end
class User < ModelObject
  def initialize(name, account)
    @name, @account = name, account
  end
  attr_accessor :name, :account
  has_image :portrait, :account
end

class Product < ModelObject
  def initialize(code, name)
    @code, @name = code, name
  end
  attr_accessor :code, :name
  has_image :front_view, :code
  has_image :side_view, :code, false
end

user1 = User.new('Steve Jobs', 'jobs')
p user1.portrait_path
p user1.icon_path

prod1 = Product.new('MB101', 'Macbook Air')
p prod1.side_view_path
p prod1.front_view_path
p prod1.icon_path

5行目のklass.class_eval の<<-ENDのヒアドキュメントの文字列の部分がRubyのコードとして評価されるんだろうけどここまではなんとか理解できた。
ただね、他の箇所は自分にとっては難しくって例えばProductとUserクラスで定義されているメソッドってhas_imageというのと、setter,getterに相当するやつしかないように見えるのに
user1 = User.new('Steve Jobs', 'jobs')
p user1.portrait_path
とやると、/img/user/portrait/job.jpgというパスが得られるっていうつながりが頭の中で全く描けなかった..

ただevalされる文字列をじっくり読んでいくと、def #{name}_pathと、def icon_pathというメソッドの定義をしている文字列があるなぁーとぼんやり考えてみた。

そうなると、user1.portrait_pathというのが、基をたどれば6行目のdef #{name}_pathに関係ありそうなのかなぁというのがうっすらと理解できた感じだけどそれでもhas_imageメソッドがやっぱりわかんない。