LoginSignup
6
6

More than 5 years have passed since last update.

Rubyデザインパターン 12日目 : DSL

Last updated at Posted at 2015-08-07

Rubyデザインパターン学習のために、自分なりに読書の結果をまとめていくことに決めました。第12日目はDSLです。(http://www.amazon.co.jp/gp/product/4894712857/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4894712857&linkCode=as2&tag=morizyun00-22)

スクリーンショット 2015-07-27 11.25.28.png

 12日目 DSL

今回はDSLです。DSLというのはドメイン特化言語と呼ばれます。

主に内部DSLについてまとめていきます。

下記のような形でバックアップを取るためのDSLを作りたいとしましょう。

backup.pr
#   README   #
Backup your textfile.

#   Usage    #
#   1. backup 'add_your_file_name'           #
#   2. backup_timestamp 'add_your_file_name' #

backup 'diary.txt'
backup_timestamp 'diary2.txt'

こういった形でバックアップの取れるDSLを書いてみましょう!
ちなみに今日のまとめは結構自力でコードを書いているので、つたない所が多いかもしれませんがご了承ください!


require 'fileutils'

class Backup
  def initialize(source)
    @backup_directory_path = 'backup'
    @source = source
    @backup_directory_full_path = File.expand_path(@backup_directory_path)
  end

  def backup
    FileUtils.mkdir_p @backup_directory_path
    FileUtils.cp(@source, @backup_directory_full_path)
  end

  def backup_timestamp
    FileUtils.mkdir_p @backup_directory_path
    file_name_timestamp = @source + fixed_timestamp
    FileUtils.copy(@source, file_name_timestamp)
    FileUtils.mv(file_name_timestamp, @backup_directory_path)
  end

  def fixed_timestamp
    Time.now.to_s.gsub('-', '').gsub(':', '').gsub(' ','').slice(0..13)
  end
end

def backup(dir)
  Backup.new(dir).backup
end

def backup_timestamp(dir)
  Backup.new(dir).backup_timestamp
end

eval(File.read('backup.txt'))
backup.txt
#   README   #
#   1. backup 'add_your_file_name'           #
#   2. backup_timestamp 'add_your_file_name' #

backup_timestamp 'diary2.txt'

実行時にevalを使っています。
メソッドをトップレベルにベタ書きしているので、また今度リファクタリングしてみようと思います!

バックアップをとりたい時は簡単で、backupbackup_timestampの後にバックアップを取りたいファイル名を入れればこのDSLを使うことができます。

evalは読み込んだものすべてをRubyスクリプトとして実行できますので、こういった実行の方法が取れますね。

ちなみにバックアップを取るとこんな感じです。

スクリーンショット 2015-08-07 20.46.21.png

 まとめ

DSLを書くと、ユーザーにとって非常に簡単な形で使えるプログラムが書けます。

ActiveRecord や Rake, Rspecなど様々な形で内部DSLを目にすることができます。

ただ、ちょっとしたタイプミスで動かなくなってしまう設計にしてしまったりすると(今回のもそうなのですが...)痛い目を見てしまうので、設計はちゃんとやりましょう!

あとevalは用法用量を守ってお使いください!(デバッグとかもやりにくくなります

参照

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6