Rubyを何で使ってるかというと、ERBがあるから。
ちょっとしたコードを自動生成したりするのに便利なの。
require 'rubygems'
require 'active_support'
require 'erb'
class Clazz
attr_accessor :name
def properties
@properties || @properties = {}
end
def properties= value
@properties = value
end
TEMPLATE = File.open("template.erb") { |f| f.read }
ERB.new(TEMPLATE, nil, '-').def_method(self, "to_code")
end
clazz = Clazz.new
clazz.name = "Taro"
clazz.properties["name1"] = "int"
clazz.properties["name2"] = "String"
puts clazz.to_code
こんな感じのRubyのコードと
public class <%= @name %>
{
<%- @properties.each do |name,type| -%>
private <%= type %> <%= name %>;
public void set<%= name.capitalize %>(<%= type %> <%= name %>) {
this.<%= name %> = <%= name %>;
}
public <%= type %> get<%= name.capitalize %>() {
return this.<%= name %>;
}
<%- end -%>
}
こんなtemplate.erbってファイルを用意して実行すると
public class Taro
{
private int name1;
public void setName1(int name1) {
this.name1 = name1;
}
public int getName1() {
return this.name1;
}
private String name2;
public void setName2(String name2) {
this.name2 = name2;
}
public String getName2() {
return this.name2;
}
}
こんなコードの出来上がり。
ん~…コードジェネレーションのコードのほうが長い!!!!
これに、ちょちょいと手を入れてみる。Clazzの定義をYAMLファイルに記述して、そこからデシリアライズしたものに対してto_codeをかけてみるように改造。
main.rb
require 'rubygems'
require 'active_support'
require 'erb'
require 'yaml'
class Clazz
attr_accessor :name
def properties
@properties || @properties = {}
end
def properties= value
@properties = value
end
TEMPLATE = File.open("template.erb") { |f| f.read }
ERB.new(TEMPLATE, nil, '-').def_method(self, "to_code")
end
classes = YAML::load_file('clazz.yml')
classes.each do |clazz|
puts clazz.to_code
end
clazz.ymlは、ためしに下のように定義してみた。
- !ruby/object:Clazz
name: Taro
properties:
name1: int
name2: String
- !ruby/object:Clazz
name: Jiro
properties:
name1: int
name2: String
- !ruby/object:Clazz
name: Sabu
properties:
foo: int
bar: String
baz: Taro
これを実行すると、今度は自動生成されるコードのほうが長くなってきたかな?
public class Taro
{
private int name1;
public void setName1(int name1) {
this.name1 = name1;
}
public int getName1() {
return this.name1;
}
private String name2;
public void setName2(String name2) {
this.name2 = name2;
}
public String getName2() {
return this.name2;
}
}
public class Jiro
{
private int name1;
public void setName1(int name1) {
this.name1 = name1;
}
public int getName1() {
return this.name1;
}
private String name2;
public void setName2(String name2) {
this.name2 = name2;
}
public String getName2() {
return this.name2;
}
}
public class Sabu
{
private Taro baz;
public void setBaz(Taro baz) {
this.baz = baz;
}
public Taro getBaz() {
return this.baz;
}
private int foo;
public void setFoo(int foo) {
this.foo = foo;
}
public int getFoo() {
return this.foo;
}
private String bar;
public void setBar(String bar) {
this.bar = bar;
}
public String getBar() {
return this.bar;
}
}
意外とお手軽にできちゃうのが素敵。