Skip to content

Instantly share code, notes, and snippets.

@masayuki14
Last active April 4, 2016 08:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masayuki14/9d1e2aace3b75369c6ec5d15cdd6a642 to your computer and use it in GitHub Desktop.
Save masayuki14/9d1e2aace3b75369c6ec5d15cdd6a642 to your computer and use it in GitHub Desktop.
メタプログラミングの簡単なサンプルコード
require 'csv'
require 'yaml'
class SupponRecord
# オープンクラスの同類
# 特定のインスタンスを再オープンして定義を追加します
class << self
attr_accessor :index_to_attr, :master_data
### マスタデータを読み込んでクラスインスタンス変数に格納
def load_master(master_dir)
@master_data ||= {}
Dir.glob(File.join(master_dir, '*.yml')) do |filename|
yaml = YAML.load_file(filename)
/(.*\/)?(.*)\.yml/.match(filename)
@master_data[$2] = yaml
end
end
### 属性の定義
# attributes = ['store_id', 'store_name'] の場合
# store_id, store_id=, store_name, store_name= のアクセッサを定義する
def define_attributes(attributes)
@index_to_attr ||= {} # indexとattrの対応
attributes.each_with_index do |attr, index|
next if attr.nil?
attr_accessor attr # attrへのアクセッサ
@index_to_attr[index] = attr
if @master_data[attr]
# マスタがある場合はそのHashを返す
# read メソッドをアラウンドエイリアスで上書き定義
alias_method("origin_#{attr}", attr)
define_method(attr) do
value = self.send("origin_#{attr}") # 設定値取得
self.class.master_data[attr][value]
end
end
end
end
end
def initialize(data)
data.each_with_index do |value, index|
attr = self.class.index_to_attr[index]
next if attr.nil? || attr.empty?
self.send("#{attr}=", value)
end
end
def bind_erb(template_path)
File.open(template_path, 'r') do |file|
yield(ERB.new(file.read).result(binding))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment