ruby LinuxやWindowsのコマンドをクラスメソッドに割り当てるクラスマクロの例
昨日の書いた「Windows セットアップ用(環境設定用)のスクリプトがあったら便利だなぁと」の第一歩として、画面解像度を変更するスクリプトを作成してみました。
そのついでに、楽にrubyのメソッドとコマンドを対応づけられないかと思い、クラスマクロ化したのでその方法について紹介します。ただし試作なので、値の無いオプションや、コマンドの実行結果に対する処理について対処していません。
作成した結果としては・・・普通にメソッドを定義した方が分かりやすく十分かもしれませんが。。。
利用例
定義方法の前に、実際の利用例について紹介します。
dcという画面解像度を変更するコマンドをruby化した例を示します。
dc -width=1024 -height=768 -depth=32
#ruby化した例 #ディスプレイの解像度を変更する Display.set do |d| d.width=1024 d.height=768 d.color=32 end
行数は増えていますが、Windowsのbatで処理するよりrubyの方が楽にかける・・・はず。実行結果に対する処理とか、制御文とか・・・。
Display.setの定義
Display.setの定義は、自作したクラスマクロbind_commandを利用しています。 Displayのクラスメソッドを追加するために、ちょっと特殊な事をしています。
#coding: utf-8 # クラスマクロを定義しているモジュール require './command_binder.rb' class Display class << self extend CommandBinder # ここでメソッドsetと'dc'を関連づけている bind_command :set, 'dc', { width: "-width=", height: "-height=", color: "-depth=", monitor: "-monitor=" } end end
command_binder.rbの実装
bind_commandメソッド中で、define_methodを使ってメソッドを定義しています。
#coding: utf-8 require 'ostruct' module CommandBinder def bind_command action_sym, command, options = nil define_method(action_sym.to_s) do |*args, &block| params = OpenStruct.new block.call params if block #コマンド文字列の作成 cmd = command.to_s params.marshal_dump.each do |key,value| real_option = options[key] if options and options.has_key? key cmd << " #{real_option}#{value}" end #コマンドの実行 `#{cmd}` end end end