
Avatar of remcopeereboom

remcopeereboom's solution

to Phone Number in the Ruby Track

Published at Jul 13 2018 · 2 comments
Test suite



Clean up user-entered phone numbers so that they can be sent SMS messages.

The North American Numbering Plan (NANP) is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: 1.

NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as area code, followed by a seven-digit local number. The first three digits of the local number represent the exchange code, followed by the unique four-digit number which is the subscriber number.

The format is usually represented as


where N is any digit from 2 through 9 and X is any digit from 0 through 9.

Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code (1) if present.

For example, the inputs

  • +1 (613)-995-0253
  • 613-995-0253
  • 1 613 995 0253
  • 613.995.0253

should all produce the output


Note: As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code.


For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

gem install minitest

If you would like color output, you can require 'minitest/pride' in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

ruby phone_number_test.rb

To include color from the command line:

ruby -r minitest/pride phone_number_test.rb


Event Manager by JumpstartLab http://tutorials.jumpstartlab.com/projects/eventmanager.html

Submitting Incomplete Solutions



require 'minitest/autorun'
require_relative 'phone_number'

# Common test data version: 1.2.0 39cba0d
class PhoneNumberTest < Minitest::Test
  def test_cleans_the_number
    # skip
    assert_equal "2234567890", PhoneNumber.clean("(223) 456-7890")

  def test_cleans_numbers_with_dots
    assert_equal "2234567890", PhoneNumber.clean("223.456.7890")

  def test_cleans_numbers_with_multiple_spaces
    assert_equal "2234567890", PhoneNumber.clean("223 456   7890   ")

  def test_invalid_when_9_digits
    assert_nil PhoneNumber.clean("123456789")

  def test_invalid_when_11_digits_does_not_start_with_a_1
    assert_nil PhoneNumber.clean("22234567890")

  def test_valid_when_11_digits_and_starting_with_1
    assert_equal "2234567890", PhoneNumber.clean("12234567890")

  def test_valid_when_11_digits_and_starting_with_1_even_with_punctuation
    assert_equal "2234567890", PhoneNumber.clean("+1 (223) 456-7890")

  def test_invalid_when_more_than_11_digits
    assert_nil PhoneNumber.clean("321234567890")

  def test_invalid_with_letters
    assert_nil PhoneNumber.clean("123-abc-7890")

  def test_invalid_with_punctuations
    assert_nil PhoneNumber.clean("123-@:!-7890")

  def test_invalid_if_area_code_does_not_start_with_2_9
    assert_nil PhoneNumber.clean("(123) 456-7890")

  def test_invalid_if_exchange_code_does_not_start_with_2_9
    assert_nil PhoneNumber.clean("(223) 056-7890")

  # Problems in exercism evolve over time, as we find better ways to ask
  # questions.
  # The version number refers to the version of the problem you solved,
  # not your solution.
  # Define a constant named VERSION inside of the top level BookKeeping
  # module, which may be placed near the end of your file.
  # In your file, it will look like this:
  # module BookKeeping
  #   VERSION = 1 # Where the version number matches the one in the test.
  # end
  # If you are curious, read more about constants on RubyDoc:
  # http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html

  def test_bookkeeping
    assert_equal 2, BookKeeping::VERSION
class PhoneNumber
  attr_reader :number

  BAD_NUMBER = '0000000000'

  def initialize(phone_number)
    @number = phone_number.chars.select{ |x| x =~ /\w/ }.join
    @number = @number[/^1?(\d{10})$/, 1]
    @number ||= BAD_NUMBER

  def area_code
    number[0, 3]

  def local_number
    "#{number[3, 3]}-#{number[6,4]}"

  def to_s
    "(#{area_code}) #{local_number}"

Community comments

Avatar of Mzuleta4

could you tell me what it's for || =?

Avatar of remcopeereboom

@Mzuleta4 commented:

could you tell me what it's for || =?

a ||= b is syntactic sugar for a = a || b. This is a way to do "memoization" for non-falsey types (basically anything but nil and false). If a is already initialized (to a non-falsey value), than a || b will short-circuit evaluate and never evaluate b. The expression a || b will then return a, so a gets assigned to a But if a is undefined, then evaluating a will return nil wich is treated as false, so b gets evaluated and the result of that will be assigned to a.

Here is a more verbose way of writing the same thing: a = b if a.nil?

What can you learn from this solution?



  • What compromises have been made?