ERB を使ってみた

まずは、ももたろさんに紹介していただいた ERB を使ってみました。
http://www.ruby-lang.org/ja/man/?cmd=view;name=erb
http://www2a.biglobe.ne.jp/~seki/ruby/erb.html


やりたかったことは、Javaソースコード生成。
まずは、Bean とプロパティの仕様を定義する Ruby のクラスを作成します。

#
# BeanDesc.rb
#

module BeanUtils

  def capitalize(s)
    if /^([a-z])(.*)$/ =~ s
      $1.upcase + $2
    else
      s
    end
  end

end

class PropertyDesc
  include BeanUtils

  attr_reader :name
  attr_reader :type

  def initialize(name, type)
    @name = name
    @type = type
  end

  def getter_name
    if 'boolean' == @type
      'is' + capitalize(@name)
    else
      'get' + capitalize(@name)
    end
  end

  def setter_name
    'set' + capitalize(@name)
  end

end

class BeanDesc
  attr_reader :name
  attr_reader :package
  attr_reader :properties

  def initialize(name, package)
    @name = name
    @package = package
    @properties = []
  end

  def add_property(name, type)
    @properties << PropertyDesc.new(name, type)
  end

end

続いて、Javaソースコードを生成する Rubyスクリプトを ERB を使って作成します。ヒアドキュメントの中で繰り返しが書けるので、すっきりしたコードになりました。

#
# ERBExample.rb
#

require 'BeanDesc'
require 'erb'

def generate_bean(desc, out = STDOUT)
  #out.puts desc.inspect
  template = <<'EOB'
/*
 * <%= desc.name %>.java
 */
package <%= desc.package %>;

/**
 * <%= desc.name %>.
 */
public class <%= desc.name %> {

% for p in desc.properties
    private <%= p.type %> <%= p.name %>;
% end
% for p in desc.properties

    /**
     * <%= p.name %> を返す。
     */
    public <%= p.type %> <%= p.getter_name %>() {
        return <%= p.name %>;
    }

    /**
     * <%= p.name %> を設定する。
     */
    public void <%= p.setter_name %>(<%= p.type %> <%= p.name %>) {
        this.<%= p.name %> = <%= p.name %>;
    }
% end

}
EOB
  out.puts ERB.new(template, nil, '%').result(binding)
end

desc = BeanDesc.new('Order', 'example')
desc.add_property('customer', 'String')
desc.add_property('product', 'String')
desc.add_property('quantity', 'int')
desc.add_property('accepted', 'boolean')

generate_bean(desc)

ちなみに、生成された Javaソースコードはこれです。

/*
 * Order.java
 */
package example;

/**
 * Order.
 */
public class Order {

    private String customer;
    private String product;
    private int quantity;
    private boolean accepted;

    /**
     * customer を返す。
     */
    public String getCustomer() {
        return customer;
    }

    /**
     * customer を設定する。
     */
    public void setCustomer(String customer) {
        this.customer = customer;
    }

    /**
     * product を返す。
     */
    public String getProduct() {
        return product;
    }

    /**
     * product を設定する。
     */
    public void setProduct(String product) {
        this.product = product;
    }

    /**
     * quantity を返す。
     */
    public int getQuantity() {
        return quantity;
    }

    /**
     * quantity を設定する。
     */
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    /**
     * accepted を返す。
     */
    public boolean isAccepted() {
        return accepted;
    }

    /**
     * accepted を設定する。
     */
    public void setAccepted(boolean accepted) {
        this.accepted = accepted;
    }

}