From: Robert Klemme Date: 2010-02-22T17:58:17+09:00 Subject: Re: Complex type-checking 2010/2/22 Ken Coar : > I have a number of methods that can take arguments in two different > forms.  As an example: > > method(tuple [, ...]) > > where 'tuple' can be things like (Point, Point, Integer) or (Numeric, > Numeric, Numeric, Numeric, Integer) (so either a Point object > representing the coordinates, or the coordinates directly). > > I realise that type-checking in Ruby is anathematic to some, but I want > to generate some intelligent error messages in some cases.  So please > let's leave the 'why do you want to do that' bit alone for now. :-) Sorry, I can't. Why do you want to do that? :-) > One meta-thought I had was for the argument vetter to be passed the > arglist and an array of allowed patterns, like > > [ >  %r/^(?:(?:Point\s*){2}\s*Integer)+$/, >  %r/^(?:(?:Numeric\s*){4}\s*Integer)+$/ > ] > > and check each tuple by doing kind_of?() of each element against the > appropriate words in the pattern. > > Which is actually turning out to be a right bugger to code, actually. Is it? def pattern_check(args, pattern) m = pattern.match(args.map{|x|x.class}.join(' ')) if m m.to_a.each_with_index do |m,i| return i if i > 0 && m end end raise ArgumentError, args.inspect end def m(*a) case pattern_check(a, %r{\A(?:(String String)|(Fixnum))\z}) when 1 printf "Two strings: %p\n", a when 2 printf "A number: %p\n", a else raise ArgumentError, a.inspect end end Method m does look ugly though. > So I'm figuring maybe someone could suggest a better method to me? Provide different methods for different arguments. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/