secret
Last active

From "Well Grounded Rubyist" by David A. Black, Listing 4.11 Simple usage of the Person Class (page 107), Listing 4.12 Implementation of the main logic of the Person class (page 108), Listing 4.13 Full implementation of Person.method_missing (page 109),

  • Download Gist
4.11_code.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
j = Person.new("Julia")
p = Person.new("Peter")
g = Person.new("Gabriel")
r = Person.new("Rebecca")
 
j.has_friends(p)
j.has_friends(r)
g.has_friends(p)
r.has_hobbies("Stargazing")
 
Person.all_with_friends(p).each do |person|
puts "#{person.name} is friends with #{p.name}"
end
 
Person.all_with_hobbies("Stargazing").each do |person|
puts "#{person.name} is into Stargazing"
end
4.12_code.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class Person
PEOPLE = []
attr_reader :name, :hobbies, :friends
def initialize(name)
@name = name
@hobbies = []
@friends = []
PEOPLE << self
end
def has_hobbies(hobby)
@hobbies << hobby
end
def has_friends(friend)
@friends << friend
end
4.13_code.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
def self.method_missing(m, *args)
method = m.to_s
if method.start_with?("all_with_")
attr = method[9..-1]
if self.public_method_defined?(attr)
PEOPLE.find_all do |person|
person.send(attr).include?(args[0])
end
else
raise ArgumentError, "Can't find #{attr}"
end
else
super
end
end
end

4.12 line 7 and 8, doing this fixes it:

@hobbies = []
@friends = []

and this is how it was in the book :-|, I made a mistake while typing...

You can modify the gist to reflect the change.

Btw. I would change the has_XYZ methods to return self. The current implementation leaks the Array member.

rklemme thank you! I edited the gist.

About the has_XYZ methods... and how I should add return self line, could you please explain the Array leaking part? It would help me understand things.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.