On Jun 6, 2008, at 10:32 PM, nahabed wrote:
consumer apps out there, I am sure I’m sure this problem has been
solved many times over 
Indeed. This one does lots of things from dealing with single fields
to dealing with three-field UIs. It also allows it to be displayed in
a few formats.
It’s one of the first Ruby things I wrote, so it’s not entirely
deconstructed to eliminate all redundancies, and may be some non-
idiomatic stuff.
I use this as a composition in my models with supporting code like so:
def phone_number
PhoneNumber.new(super)
end
def phone_number=(phone)
super PhoneNumber.new(phone).to_s
end
– gw
class PhoneNumber
#------------------------------------------------------------
def initialize(parts=’’)
self.[] parts
end
def set(parts)
self.[] parts
end
def [] (parts)
if parts.is_a?(String)
@phone_number = parts.gsub(/\D/,’’)
elsif parts.is_a?(Hash)
self.pack!(parts)
end
end
#: -
#------------------------------------------------------------
def to_s
return @phone_number.to_s
end
def raw
@phone_number
end
def has_areacode?
areacode != ‘000’
end
def areacode
return @phone_number[0,3]
end
def prefix
return @phone_number[3,3]
end
def number
return @phone_number[6,4]
end
def extension
return @phone_number[10,6]
end
#:-
#------------------------------------------------------------
def formatted(format=’-’)
return self.formatted_with(format)
end
#------------------------------------------------------------
def formatted_with(format=’-’)
formats any number with at least 7 digits and a maximum of 16
formatted_number = String.new
number_length = @phone_number.size
if (number_length == 7)
@phone_number = ‘000’ + @phone_number
elsif (number_length < 7) || (number_length == 8) ||
(number_length == 9) || (number_length > 16)
return @phone_number
end
if format == ‘(’
separator = ‘-’
formatted_areacode = ‘(’ + areacode + ') ’
elsif format == ‘/’
separator = ‘-’
formatted_areacode = areacode + ‘/’
else
separator = format
formatted_areacode = (areacode + separator)
end
formatted_number += formatted_areacode
formatted_number += @phone_number[3,3]
formatted_number += separator
formatted_number += @phone_number[6,4]
if @phone_number.size > 10
formatted_number += ’ x’
formatted_number += @phone_number[10,6]
end
return formatted_number
end
#------------------------------------------------------------
def unpack
return {
:areacode => self.areacode,
:prefix => self.prefix,
:number => self.number,
:extension => self.extension}
end
#------------------------------------------------------------
def pack(parts)
phArea = ‘’
phPrefix = ‘’
phNumber = ‘’
phExtension = ‘’
if parts.size >= 3
if parts.is_a?(Array)
phArea = parts[0].to_s
phPrefix = parts[1].to_s
phNumber = parts[3].to_s
if parts.size == 4
phExtension = parts[4].to_s
end
elsif parts.is_a?(Hash)
phArea = parts[:areacode].to_s
phPrefix = parts[:prefix].to_s
phNumber = parts[:number].to_s
phExtension = parts[:extension].to_s
end
end
return phArea + phPrefix + phNumber + phExtension
end
#------------------------------------------------------------
def pack!(parts)
@phone_number = pack(parts)
end
end
=begin
home = PhoneNumber.new(‘800/555-2468 x012’)
or
home = PhoneNumber.new
home[‘800/555-2468 x012’]
or
home = PhoneNumber.new
({:areacode=>‘800’, :prefix=>‘555’, :number=>‘2020’})
puts home.raw
puts home.areacode
puts home.prefix
puts home.number
puts home.extension
puts home.formatted
puts home.formatted_with(’(’)
puts home.formatted_with(’.’)
puts home.formatted_with(’/’)
puts home.to_s
puts home.pack({:areacode=>‘555’, :prefix=>‘888’, :number=>‘1212’})
p home.unpack
puts home.pack!({:areacode=>‘555’, :prefix=>‘888’, :number=>‘1212’})
puts home.formatted
=end