Skip to content

Instantly share code, notes, and snippets.

@mveytsman
Created June 20, 2014 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mveytsman/00d9b8c7410fb218c2b1 to your computer and use it in GitHub Desktop.
Save mveytsman/00d9b8c7410fb218c2b1 to your computer and use it in GitHub Desktop.
Hacker School Phonebook
#!/usr/bin/env ruby
require 'thor'
class PhoneBookCLI < Thor
no_commands do
def wrap_errors(&block)
begin
instance_eval &block
rescue Exception => e
say "#{e.message}", :red
exit
end
end
end
desc "create FILENAME", "create a new phonebook at FILENAME"
def create(filename)
#TODO: check that path is actually in current directory
wrap_errors do
Phonebook.create(filename)
end
say "created phonebook #{filename} in the current directory"
end
desc "lookup PATTERN PHONEBOOK", "lookup PATTERN in PHONEBOOK"
def lookup(pattern, filename)
wrap_errors do
numbers = Phonebook.new(filename).lookup(pattern)
numbers.each do |name, number|
say "#{name} #{number}"
end
end
end
desc "reverse-lookup NUMBER PHONEBOOK", "reverse lookup NUMBER from PHONEBOOK"
def reverse_lookup(number, filename)
wrap_errors do
phonebook = Phonebook.new(filename)
numbers = phonebook.reverse_lookup(number)
numbers.each do |name, number|
say "#{name} #{number}"
end
end
end
desc "add NAME NUMBER PHONEBOOK", "add NAME, NUMBER to PHONEBOOK"
def add(name, number, filename)
wrap_errors do
phonebook = Phonebook.new(filename)
phonebook.save!
say "Added #{name}, #{number} to #{filename}"
end
end
desc "change NAME NUMBER PHONEBOOK", "change NAME to NUMBER in PHONEBOOK"
def change(name, number, filename)
wrap_errors do
phonebook = Phonebook.new(filename)
phonebook.change(name, number)
phonebook.save!
say "Changed #{name} to #{number} in #{filename}"
end
end
desc "remove NAME PHONEBOOK", "remove NAME from PHONEBOOK"
def remove(name, phonebook)
wrap_errors do
phonebook = Phonebook.new(filename)
phonebook.remove(name, number)
phonebook.save!
say "Removed #{name} from #{filename}"
end
end
end
class Phonebook
def self.create(filename)
if File.exists?(filename)
raise "Error: file #{filename} already exists"
end
#Creates a new empty phonebook
File.open(filename,"w") do |f|
f.write({}.to_yaml)
end
end
def initialize(filename)
unless File.exists?(filename)
raise "Error: phonebook #{filename} doesn't exist"
exit
end
@filename = filename
@phonebook = YAML.load_file(filename)
end
def save!
File.open(@filename,"w") do |f|
f.write(@phonebook.to_yaml)
end
end
def add(name, number)
if @phonebook[name]
raise "Error: #{name} is already in phonebook"
end
@phonebook[name] = number
end
def change(name,number)
unless @phonebook[name]
raise "Error: #{name} is not in phonebook"
end
@phonebook[name] = number
end
def remove(name,number)
unless @phonebook[name]
raise "Error: #{name} is not in phonebook"
end
@phonebook[name] = nil
end
def lookup(pattern)
results = @phonebook.select { |k,val| k.start_with? pattern}
if results.empty?
raise "Error: #{pattern} not found in phonebook"
end
results
end
def reverse_lookup(number)
results = @phonebook.select{ |k, val| val == number}
if results.empty?
raise "Error: #{number} not found in phonebook"
end
results
end
end
PhoneBookCLI.start(ARGV)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment