you should come back to it and evaluate your progress, maybe try to refactor
the code to incorporate the experience you have gained.
There are a few things, notice the syntax highlighting on line 46, you need
to either escape that apostrophe, or else wrap your string in double quotes.
You have
class String
def monkey?
self != (Math::PI) and self != 'BYE'
end
end
But this is a little tricky. Your variable was initially a String, but when
you assigned it the value of Math::PI, it became a Float. So that method
monkey? does not exist on for Floats. Since it is defined in the String
class, self will always be a string, so it can never be equal to Math::PI
Monkey patching just means that you are adding functionality to the class in
some unofficial way, changing it (usually at run-time) with your own code.
It can cause issues, and be unintuitive, so it is sometimes looked down on,
but that doesn't mean it should always be avoided. In fact, I'd argue that
in a small program like this, which is built around the state of the string
being shouted or not (it is the deaf grandma problem, after all), that it
should be very intuitive what that method does, it is simple and
straightforward, and is a cleaner solution, both in terms of OO, and in
terms of the nature of the problem, than defining a function to receive this
as a parameter.
However, your monkey method would be much better served as a function that
receives a value, because then it can receive any value at all (where
shouted? indicates the state of the string, monkey? does not, because a
Float is not a string).
So you could do something like this
def monkey?( var )
var != Math::PI && var != "BYE"
end
Then instead of saying something like
elsif reply.monkey?
you would say
elsif monkey?(reply)
Passing the reply to the monkey?() function instead of calling the .monkey?
method on it.
Now, that said, if you follow your program logic, you have
if reply == (Math::PI)
puts 'Do you know when I was your age I was a model?'
reply = gets.chomp
end
which gets executed first, so really, reply will never be Math::PI when it
gets to the reply.mokey? call, because this code will ensure that it becomes
the input.
Also, as far as using constants goes, Math::PI doesn't make a lot of sense.
I understand thats the point of it but I think a better choice would be
to use a symbol. You can think of a symbol as a string with the properties
of a numeric constant (granted there is more to it than that). Strings are
defined like this "string" and symbols are defined like this :symbol So I
would suggest that instead of using Math::PI, you use a symbol that makes
sense for you, something like :uninitialized Then when you look at your code
later, seeing :uninitialized in all places where you currently have Math::PI
will make a lot more sense.
Also, an uninitialized variable is nil by default, you should probably try
to get comfortable with this, because that will be the case for almost
everything in Ruby. So with that understanding, you could bypass the need
for a constant altogether.
Hope that helps, glad you're making progress, and keep at it
···
On Thu, Sep 10, 2009 at 2:54 AM, Chris Logan <t-logan3@hotmail.com> wrote:
Well, after hearing all of your guy's advice, I thought it over and
finally came up with the answers. Its monkey patched (those words make
me laugh) but it works bug free and you have no idea how elated I am at
that (well maybe you do). Monkey patching may be bad but it got my job
done. Maybe after I get a lot more experience I will find out how to do
this without it but for now I'm satisfied and moving on in the tutorial.
I was going to post it but I remebered what one of the earlier posts
said so I did this.
http://pastie.org/612032
I was hoping for a couple honest opionions.
Any comments or any more tips are greatly appreciated.
You have all been a huge help. Thank you all.
Chris
--
Posted via http://www.ruby-forum.com/\.
Hi, Chris, I'm glad you got it working. After you code a little bit longer,