Class: Phoner::Phone
Constant Summary collapse
- NUMBER =
'([0-9]{1,8})$'
- DEFAULT_AREA_CODE =
any 3 digits
'[0-9][0-9][0-9]'
- @@n1_length =
default length of first number part
3
- @@named_formats =
{ :default => "+%c%a%n", :default_with_extension => "+%c%a%nx%x", :europe => '+%c (0) %a %f %l', :us => "(%a) %f-%l" }
Instance Attribute Summary collapse
-
#area_code ⇒ Object
Returns the value of attribute area_code.
-
#country_code ⇒ Object
Returns the value of attribute country_code.
-
#extension ⇒ Object
Returns the value of attribute extension.
-
#number ⇒ Object
Returns the value of attribute number.
Class Method Summary collapse
-
.detect_country(string) ⇒ Object
detect country from the string entered.
-
.detect_format(string_with_number, country) ⇒ Object
detect format (from FORMATS) of input string.
-
.extract_extension(string) ⇒ Object
pull off anything that look like an extension TODO: refactor things so this doesn’t change string as a side effect.
- .formats(country) ⇒ Object
-
.normalize(string_with_number) ⇒ Object
fix string so it’s easier to parse, remove extra characters etc.
-
.parse(string, options = {}) ⇒ Object
create a new phone number by parsing a string the format of the string is detect automatically (from FORMATS).
-
.split_to_parts(string, options = {}) ⇒ Object
split string into hash with keys :country_code, :area_code and :number.
-
.valid?(string) ⇒ Boolean
is this string a valid phone number?.
Instance Method Summary collapse
-
#==(other) ⇒ Object
comparison of 2 phone objects.
-
#area_code_long ⇒ Object
format area_code with trailing zero (e.g. 91 as 091) format area_code with trailing zero (e.g. 91 as 091).
-
#format(fmt) ⇒ Object
Formats the phone number.
-
#has_default_area_code? ⇒ Boolean
does this number belong to the default area code?.
-
#has_default_country_code? ⇒ Boolean
does this number belong to the default country code?.
-
#initialize(*hash_or_args) ⇒ Phone
constructor
A new instance of Phone.
-
#number1 ⇒ Object
first n characters of :number.
-
#number2 ⇒ Object
everything left from number after the first n characters (see number1).
-
#to_s ⇒ Object
the default format is “+%c%a%n”.
Constructor Details
#initialize(*hash_or_args) ⇒ Phone
Returns a new instance of Phone.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/phone.rb', line 39 def initialize(*hash_or_args) if hash_or_args.first.is_a?(Hash) hash_or_args = hash_or_args.first keys = {:number => :number, :area_code => :area_code, :country_code => :country_code, :extension => :extension} else keys = {:number => 0, :area_code => 1, :country_code => 2, :extension => 3} end self.number = hash_or_args[ keys[:number] ] self.area_code = hash_or_args[ keys[:area_code] ] || self.default_area_code self.country_code = hash_or_args[ keys[:country_code] ] || self.default_country_code self.extension = hash_or_args[ keys[:extension] ] raise NumberError, "Must enter number" if self.number.blank? raise AreaCodeError, "Must enter area code or set default area code" if self.area_code.blank? raise CountryCodeError, "Must enter country code or set default country code" if self.country_code.blank? end |
Instance Attribute Details
#area_code ⇒ Object
Returns the value of attribute area_code.
21 22 23 |
# File 'lib/phone.rb', line 21 def area_code @area_code end |
#country_code ⇒ Object
Returns the value of attribute country_code.
21 22 23 |
# File 'lib/phone.rb', line 21 def country_code @country_code end |
#extension ⇒ Object
Returns the value of attribute extension.
21 22 23 |
# File 'lib/phone.rb', line 21 def extension @extension end |
#number ⇒ Object
Returns the value of attribute number.
21 22 23 |
# File 'lib/phone.rb', line 21 def number @number end |
Class Method Details
.detect_country(string) ⇒ Object
detect country from the string entered
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/phone.rb', line 124 def self.detect_country(string) detected_country = nil # find if the number has a country code Country.all.each_pair do |country_code, country| if string =~ country.country_code_regexp detected_country = country end end detected_country end |
.detect_format(string_with_number, country) ⇒ Object
detect format (from FORMATS) of input string
146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/phone.rb', line 146 def self.detect_format(string_with_number, country) arr = [] formats(country).each_pair do |format, regexp| arr << format if string_with_number =~ regexp end # raise "Detected more than 1 format for #{string_with_number}" if arr.size > 1 if arr.length > 1 # puts %Q{detect_format: more than one format found - #{arr.inspect}} return :really_short end arr.first end |
.extract_extension(string) ⇒ Object
pull off anything that look like an extension TODO: refactor things so this doesn’t change string as a side effect
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/phone.rb', line 168 def self.extract_extension(string) return nil if string.nil? if string.sub! /[ ]*(ext|ex|x|xt|#|:)+[^0-9]*\(*([-0-9]{1,})\)*#?$/i, '' extension = $2 return extension end # # We already returned any recognizable extension. # However, we might still have extra junk to the right # of the phone number proper, so just chop it off. # idx = string.rindex(/[0-9]/) return nil if idx.nil? return nil if idx == (string.length - 1) # at the end string.slice!((idx+1)..-1) # chop it return nil end |
.formats(country) ⇒ Object
135 136 137 138 139 140 141 142 143 |
# File 'lib/phone.rb', line 135 def self.formats(country) area_code_regexp = country.area_code || DEFAULT_AREA_CODE { # 047451588, 013668734 :short => Regexp.new('^0?(' + area_code_regexp + ')' + NUMBER), # 451588 :really_short => Regexp.new('^' + NUMBER) } end |
.normalize(string_with_number) ⇒ Object
fix string so it’s easier to parse, remove extra characters etc.
161 162 163 |
# File 'lib/phone.rb', line 161 def self.normalize(string_with_number) string_with_number.gsub("(0)", "").gsub(/[^0-9+]/, '').gsub(/^00/, '+').gsub(/^\+00/, '+').gsub(/^\+0/, '+') end |
.parse(string, options = {}) ⇒ Object
create a new phone number by parsing a string the format of the string is detect automatically (from FORMATS)
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/phone.rb', line 59 def self.parse(string, ={}) if string.present? Country.load extension = extract_extension(string) string = normalize(string) [:country_code] ||= self.default_country_code [:area_code] ||= self.default_area_code parts = split_to_parts(string, ) pn = Phone.new(parts) if parts if pn.present? and extension.present? pn.extension = extension end return pn end end |
.split_to_parts(string, options = {}) ⇒ Object
split string into hash with keys :country_code, :area_code and :number
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/phone.rb', line 89 def self.split_to_parts(string, = {}) country = detect_country(string) if country [:country_code] = country.country_code string = string.gsub(country.country_code_regexp, '0') else if [:country_code] country = Country.find_by_country_code [:country_code] end end if country.nil? if [:country_code].nil? raise CountryCodeError, "Must enter country code or set default country code" else raise CountryCodeError, "Could not find country with country code #{options[:country_code]}" end end format = detect_format(string, country) return nil if format.nil? parts = string.match formats(country)[format] case format when :short {:number => parts[2], :area_code => parts[1], :country_code => [:country_code]} when :really_short {:number => parts[1], :area_code => [:area_code], :country_code => [:country_code]} end end |
.valid?(string) ⇒ Boolean
is this string a valid phone number?
79 80 81 82 83 84 85 86 |
# File 'lib/phone.rb', line 79 def self.valid?(string) begin parse(string).present? # if we encountered exceptions (missing country code, missing area code etc) rescue PhoneError return false end end |
Instance Method Details
#==(other) ⇒ Object
comparison of 2 phone objects
242 243 244 245 |
# File 'lib/phone.rb', line 242 def ==(other) methods = [:country_code, :area_code, :number, :extension] methods.all? { |method| other.respond_to?(method) && send(method) == other.send(method) } end |
#area_code_long ⇒ Object
format area_code with trailing zero (e.g. 91 as 091) format area_code with trailing zero (e.g. 91 as 091)
188 189 190 |
# File 'lib/phone.rb', line 188 def area_code_long "0" + area_code if area_code end |
#format(fmt) ⇒ Object
Formats the phone number.
if the method argument is a String, it is used as a format string, with the following fields being interpolated:
-
%c - country_code (385)
-
%a - area_code (91)
-
%A - area_code with leading zero (091)
-
%n - number (5125486)
-
%f - first @@n1_length characters of number (configured through Phone.n1_length), default is 3 (512)
-
%l - last characters of number (5486)
-
%x - entire extension
if the method argument is a Symbol, it is used as a lookup key for a format String in Phone.named_formats
pn.format(:europe)
217 218 219 220 221 222 223 224 |
# File 'lib/phone.rb', line 217 def format(fmt) if fmt.is_a?(Symbol) raise "The format #{fmt} doesn't exist'" unless named_formats.has_key?(fmt) format_number named_formats[fmt] else format_number(fmt) end end |
#has_default_area_code? ⇒ Boolean
does this number belong to the default area code?
237 238 239 |
# File 'lib/phone.rb', line 237 def has_default_area_code? area_code == self.class.default_area_code end |
#has_default_country_code? ⇒ Boolean
does this number belong to the default country code?
232 233 234 |
# File 'lib/phone.rb', line 232 def has_default_country_code? country_code == self.class.default_country_code end |
#number1 ⇒ Object
first n characters of :number
193 194 195 |
# File 'lib/phone.rb', line 193 def number1 number[0...self.class.n1_length] end |
#number2 ⇒ Object
everything left from number after the first n characters (see number1)
198 199 200 201 |
# File 'lib/phone.rb', line 198 def number2 n2_length = number.size - self.class.n1_length number[-n2_length, n2_length] end |
#to_s ⇒ Object
the default format is “+%c%a%n”
227 228 229 |
# File 'lib/phone.rb', line 227 def to_s format(:default) end |