Skip to content

Instantly share code, notes, and snippets.

@clicube
Last active December 11, 2015 04:19
Show Gist options
  • Save clicube/4544121 to your computer and use it in GitHub Desktop.
Save clicube/4544121 to your computer and use it in GitHub Desktop.
validate arguments of instance method
module ArgsValidator
def self.validate_args name, args, rules, klass
([args.length,rules.length].min).times do |i|
arg = args[i]
rule = rules[i]
next if rule == :any
rule = rule.class unless rule.class <= Class
unless arg.class <= rule
th = %w[st nd rd][i%10] || 'th'
raise ArgumentError.new("#{i+1}#{th} argument of #{klass.name}##{name} must be #{rule} but passed #{arg.class.name}")
end
end
end
def validate_args name, *rules
wraped_method = instance_method(name)
define_method(name) do |*args|
begin
ArgsValidator.validate_args name, args, rules, self.class
rescue ArgumentError => e
4.times{ e.backtrace.shift }
raise e
end
wraped_method.bind(self).call(*args)
end
end
private :validate_args
end
if $0 == __FILE__
class Neko
extend ArgsValidator
def nyan(count,how="nyan")
count.times{ puts how }
end
validate_args :nyan, Integer, String
end
Neko.new.nyan(1,"wan") # => pass (say wan)
Neko.new.nyan(2) # => pass (say nyan nyan)
Neko.new.nyan("one","wan") # => ArgumentError
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment