Skip to content

Instantly share code, notes, and snippets.

@cutalion
Created October 11, 2011 16:06
Show Gist options
  • Save cutalion/1278518 to your computer and use it in GitHub Desktop.
Save cutalion/1278518 to your computer and use it in GitHub Desktop.
# Usage
#
# class Rectangle
# include TypeCast
#
# ...
#
# attr_accessor :width, :height, :fill
# type_cast :width, :height, :method => :to_f
# type_cast :fill, :allow_nil => false, :method => lambda { |value| !!value }
#
# ...
#
# def area
# width * height
# end
#
# def draw
# ...
# fill_with_color(color) if fill
# ...
# end
# end
#
#
# r = Rectangle.new :width => "10", :height => 12, :fill => "yes"
# r.width #=> 10.0
# r.height #=> 12.0
# r.fill #=> true
module TypeCast
extend ActiveSupport::Concern
module ClassMethods
def type_cast(*args)
options = args.extract_options!
options[:allow_nil] = true if options[:allow_nil].nil?
raise ArgumentError, "Undefined method for type casting" if options[:method].nil?
raise ArgumentError, "Undefined attribute for type casting" if args.empty?
args.each do |attr|
define_method "#{attr}_with_type_cast=" do |value|
value = if value.nil? && options[:allow_nil]
nil
else
options[:method].is_a?(Proc) ? options[:method].call(value) : value.send(options[:method])
end
send("#{attr}_without_type_cast=", value)
end
alias_method_chain :"#{attr}=", :type_cast
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment