概要
activesupport::concernによってモジュールのクラスメソッドincludeを簡潔にする
内容
RailsのActiveSupport::Concernを利用することによって
Rails以外のRubyプロジェクトでもモジュールのクラスメソッドincludeを簡潔に出来ます。
サンプル仕様
下記記事で照会した、標準入力Validation用のモジュールをサンプルとします。
Ruby | 標準入出力処理時のValidationをクラスマクロで共通化Comments
http://d.hatena.ne.jp/tbpg/20130625/1372165415
ActiveSupport::Concernを利用しなかった場合のモジュール
standard_io.rb
module StandardIo def self.included(klazz) klazz.extend(ClassMethods) end def validate self.methods.grep(/^validate_.*/).each do |m| return false unless method(m).call end true end def args_has_index?(index) $*.size > index end module ClassMethods def validate_args_counts(count) define_method "validate_args_counts" do $*.size == count end end def validate_us_dollar(index) define_method "validate_us_dollar_#{index}" do return false unless args_has_index?(index) if ($*[index] =~ /^[\d\.]+$/) return true end false end end def validate_file(index) define_method "validate_file_#{index}" do return false unless args_has_index?(index) FileTest.exist?($*[index]) end end end end
利用側クラス
standard_io_user.rb
# encoding: utf-8 require_relative "standard_io" class Hoge include StandardIo validate_args_counts 4 validate_us_dollar 0 validate_us_dollar 1 validate_file 2 validate_file 3 def validate_range() _validate_range(0, (1..3)) end def _validate_range(index, range) range.include?($*[index].to_i) end end hoge = Hoge.new puts hoge.validate
変更前結果
$ruby standard_io_user.rb 1 2 standard_io.rb active_suport_concern.yml true
ActiveSupport::Concernを利用した場合のモジュール
# encoding: utf-8 require 'active_support' module StandardIoAfter extend ActiveSupport::Concern module ClassMethods def validate_args_counts(count) define_method "validate_args_counts" do $*.size == count end end def validate_us_dollar(index) define_method "validate_us_dollar_#{index}" do return false unless args_has_index?(index) if ($*[index] =~ /^[\d\.]+$/) return true end false end end def validate_file(index) define_method "validate_file_#{index}" do return false unless args_has_index?(index) FileTest.exist?($*[index]) end end end def validate self.methods.grep(/^validate_.*/).each do |m| return false unless method(m).call end true end def args_has_index?(index) $*.size > index end end
利用側クラス
# encoding: utf-8 require_relative "standard_io_after" class HogeAfter include StandardIoAfter validate_args_counts 4 validate_us_dollar 0 validate_us_dollar 1 validate_file 2 validate_file 3 def validate_range() _validate_range(0, (1..3)) end def _validate_range(index, range) range.include?($*[index].to_i) end end hoge = HogeAfter.new puts hoge.validate
変更後結果
$ruby standard_io_user_after.rb 1 2 standard_io.rb active_suport_concern.yml true