-
-
Save adkron/6148836 to your computer and use it in GitHub Desktop.
I edited this in the browser so I might not be quite right, but I think I got it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class << Silent = Object.new | |
def heard?(other) | |
other.empty? | |
end | |
def respond | |
"Fine. Be that way." | |
end | |
end | |
class << Question = Object.new | |
def heard?(other) | |
other.end_with?("?") | |
end | |
def respond | |
"Sure." | |
end | |
end | |
class << Shout = Object.new | |
def heard?(other) | |
other == other.upcase | |
end | |
def respond | |
"Woah, chill out!" | |
end | |
end | |
class << Default = Object.new | |
def respond | |
"Whatever." | |
end | |
end | |
class Bob | |
def self.add_thought(thought) | |
@thoughts.push thought | |
end | |
@thoughts = [] | |
add_thought Silent | |
add_thought Question | |
add_thought Shout | |
def hey(phrase) | |
think_about(heard(phrase)).respond | |
end | |
def heard(phrase) | |
String(phrase) | |
end | |
def think_about(might_have_heard) | |
thoughts.find(-> { Default }) { |thought| thought.heard?(might_have_heard) } | |
end | |
def self.thoughts | |
@thoughts | |
end | |
private | |
def thoughts | |
self.class.thoughts | |
end | |
end |
I agree that this is a more OO version of Bob. I like it.
My thought when reading it was that I might add a trivial one class method DSL for defining new responses. That's just a random idea I had.
@JEG2, thanks. I think that is a good idea. Something like:
@responders = []
def self.add_responder(responder)
@responders.push responder
end
add_responder Silent
add_responder Question
I think that could be good. I also like the idea of adding multiple responders. Maybe this would be better to do on an instance?
@JEG2 is this new version what you were thinking?
Oh, I read that all wrong. You said to define responses.
respond_with "Fine. Be that way.", when: ->(other) { other.empty? }
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@markijbema this has nothing to do with the if construct. If I had these as a bunch of if statements and the silent if was not first we would have the same issue. The real problem is that Shout does not check that the string contains a least some letters. With this configuration I can easily write tests to test that piece in isolation. In no way does this have to do with the construct that I used here. This will still only check Shout when Silent is false.
See what I mean?
The other thing is that I can easily make this expandable and inject different thoughts. Now I am not bound to a set of hard coded circumstances. IMHO that makes this code infinitely more maintainable than a string of if statements. If I change this to inject thoughts then I have truly gotten this class to a good example of the open/closed principle. Bob no longer has reason to change. The if construct becomes larger and more error prone as I continue to add more.