Rubyクラスを自動生成するRubyスクリプトを作ってみる


いろいろ思うところあってQiitaのアカウントを消したのでここに書いておく

目的

  • 仕事でよくあるボイラープレート的なコードを自動で作れたらいいなあ

Scope

  • クラス名とフィールドをコマンドから与えて、共通の「something」メソッドを持ったrubyクラスファイルを自動生成します。
  • 完全自動化というよりは、「自分で作り込んでいく箇所でない箇所」を効率的に作成できればOK

I/O

Input

とりあえずRails Scaffold的なインタフェースを目指してみます。
入力するコマンドはこれ
ruby class_gen.rb AwesomeBook name price

Output

期待する出力は、以下のファイルが作成されること

class AwesomeBook
  attr_accessor :name,:price
  def initialize(name,price)
    @name = name
    @price = price
  end
  def something
    puts 'please implement me!'
  end
end

Code

  • Ruby標準で組み込まれているerbを使います。
class <%= class_name %>
  <%- unless fields.nil? -%>
  attr_accessor :<%= fields.join(',:')%>
  def initialize(<%= fields.join(',')%>)
    <%- fields.each do |field| -%>
      @<%= field %> = <%= field %>
    <%- end -%>
  end
  <%- end ->
  def something
    puts 'please implement me!'
  end
end

実行スクリプトは以下

require 'erb'

class String
  def to_snake
     gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
    .gsub(/([a-z\d])([A-Z])/, '\1_\2')
    .tr('-', '_')
    .downcase
  end
end

class_name = ARGV[0]
fields = ARGV.slice(1..ARGV.size - 1) if ARGV.size > 1
erb_context = ERB.new(File.read('./erb/sample_class_gen.erb'), nil, '-')

binded_result = erb_context.result(binding)
output_file_name = "#{class_name.to_snake}.rb"

File.open(output_file_name, 'w') do |file|
file.write(binded_result)
end

More

  • Rakeタスクに乗せたりとかするとより実用性UP