Jeffrey Moss
3/23/2005 11:42:00 PM
free your mind neo
right, there is no spoon
yeah
----- Original Message -----
From: "Florian Gross" <flgr@ccan.de>
Newsgroups: comp.lang.ruby
To: "ruby-talk ML" <ruby-talk@ruby-lang.org>
Sent: Wednesday, March 23, 2005 4:34 PM
Subject: Re: Credit Card Verification as an exercise
> Jeffrey Moss wrote:
>
>> Couldn't find any credit card verification code written in ruby so I
>> wrote up my own. This code turns out a lot smaller than the perl
>> version I have been using. I thought it was an interesting exercise,
>> here is how its done, if anybody can improve on what I've done I'd be
>> impressed. %*
>
> Nice code and I guess it will be quite useful as well! Thanks for
> posting this here.
>
>> class CreditCard < ActiveRecord::Base
>>
>> def before_save
>> if number_is_valid && number_matches_type
>> ...
>> end
>> end
>>
>> def number_is_valid
>
> Guess, I'd rename this to 'number_valid?'. :)
>
>> total = 0
>> number.gsub(/[^0-9]/, '').reverse.scan(/(\d)(\d){0,1}/) do |ud,ad|
>> (ad.to_i*2).to_s.each {|d| total = total + d.to_i} if ad
>> total = total + ud.to_i
>> end
>> total % 10 == 0 ? false : true
>
> Hm, why not simply "total % 10 != 0"?
>
>> end
>>
>> def number_matches_type
>
> Might be nice to append a question mark here as well.
>
>> digit_length = number.length
>> if card_type == 'visa'
>> if (digit_length == 16) || (digit_length == 13)
>> return true if number[/^\d/].to_i == 4
>> end
>> elsif card_type == 'mastercard'
>> if digit_length == 16
>> return true if (51..55).to_a.include?(number[0..1].to_i)
>
> Hmmm, why the .to_a call?
>
>> end
>> elsif card_type == 'amex'
>> if digit_length == 15
>> return true if [34,37].include?(number[0..1].to_i)
>> end
>> elsif card_type == 'discover'
>> if digit_length == 16
>> return true if number[0..3].to_i == 6011
>> end
>> end
>> end
>> end
>
> I think all this returns are superfluous -- after all Ruby will return
> the result of evaluating the matching if clause.
>
> Oh, and I think this is a good case for the case construct:
>
> case card_type
> when 'visa' then
> [13, 16].include?(digit_length) and number[0, 1] == "4"
> when 'mastercard' then
> digit_length == 16 and ("51" .. "55").include?(number[0, 2])
> when 'amex' then
> digit_length == 15 and %w(34 37).include?(number[0, 2])
> when 'discover' then
> digit_length == 16 and number[0, 4] == "6011"
> end
>