日々の記録。

プログラミングのメモや感じた事などを記録。

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