I just squashed a bug that had me scratching my head for at least a good half-hour or so involving a class constant that kept on getting changed. Here’s the setup (anonymized so that I’m not exposing gooey proprietary secrets):
class WebTransaction # Base URL for transaction web service SERVICE_URL = "http://accountingservice.com/" def transaction_url url = SERVICE_URL url << "VAL1=foo" url << "&VAL2=bar" url end end |
The class is meant to represent a transaction being posted against a rather odd web service that actually uses GET rather than POST for posting transactions (bad web service!). In my actual code, the URL parameters appended to the SERVICE_URL base would be determined on a per-object basis but I’ve simplified it here.
Here’s the punchline: SERVICE_URL
was changing! Calls to transaction_url
would keep on appending more variables to it. If you’re particularly clever with Ruby, you’ve already figured out exactly why. But if you’re scratching your head like I was, here are some hints:
- In Ruby, constants aren’t. In fact, they’re really no different from variables except for the fact that Ruby detects that variable names in all-caps are probably supposed to stay constant and warns if you try to assign to them.
<<
, for strings, will append to the end of the string.- Ruby strings are mutable. That is, operations on a string variable will usually be done in place, rather than returning a new string. (Method calls, on the other hand, are a different story!)
- Assigning a String variable to another String variable will assign the reference. That is, the two variables will be pointing at the same object.
Hit the jump to see the solution to this little mystery…
Read the rest of this entry »