5 ms·
It's the shiny new toy every new ruby dev wants to play with. Once they get bit in the butt by some really obscure bug that requires the correct combination of
by stewiecat 18y ago
It's the shiny new toy every new ruby dev wants to play with. Once they get bit in the butt by some really obscure bug that requires the correct combination of 10 gems to reproduce they'll realize that maybe monkeypatching isn't such a hot idea, until then we'll have a bazillion versions of String.
- raganwald 18y agoI encourage Ruby programmers to monkey-patch in their "leaf projects." If you want to write Array#sum for your web app, I say go ahead, it's your butt and you are old enough to deal with the consequences. However, when writing gems, plugins, frameworks, any code that others will use is a different story: Now your "clients" suffer the consequences of your choices. A story about how a web app was broken by installing the Classifier gem due to an Array#sum conflict wouldn't be a story. You change your web app and move along smartly. But who in tarnation is up for patching gems to deal with the conflicts caused by gems patching Array on each other. Ugh.
- dasil003 18y agoThis very consideration led me to redefine nil? on an inner class in my SafeNestedHash gem. It's definitely ugly and weird, but I needed a method that existed on object so I can guarantee it's everywhere. Any other thoughts on how to solve this problem? http://github.com/dasil003/safe-nested-hash/tree/master http://github.com/dasil003/safe-nested-hash/tree/master
- pdubroy 18y agoWhy not just define a function in your code, rather than redefining 'nil?'?
- jfarmer 18y agoBecause you want to be able to pass it to functions that expect Hash semantics? Yay weak typing! cough
- dasil003 18y agoIt's a kludge so that people don't have to write: if hash[:a][:long][:key][:chain].is_a?(SafeNestedHash::UndefinedHash) Instead they can just say: if hash[:a][:long][:key][:chain].nil? If the nested hash IS defined it could be any type under the sun, therefore a method has to be defined on object, and nil? seemed the only reasonable choice.
- tdavis 18y agoMaybe I don't really understand Ruby, but isn't it basically a duck-typed language? Why would you be checking the type at all (which I am assuming `is_a?` does)? Type checking is evil for weakly-typed languages. Either it implements what you need it to implement or has some property value, otherwise it should throw an exception. What are you testing for here? To see if the hash is empty or something? What makes an "UndefinedHash" undefined? If it IS defined, then it should be assumed to be the type of object you are looking for until the code tries to do something that breaks on a non-supported type.
- dasil003 18y agoThe purpose of the SafeNestedHash is to be able to directly reference or assign deep nested hashes without initializing every level. Ruby will throw an error if you do this with a regular hash because the first undefined level returns nil and nil does not respond to the [] method (square brackets are just a method in Ruby). The UndefinedHash is a class that stands in for nil so we don't get an error as we make a deep reference and it also keeps track of the keys so that if there is an assignment at the end it can initialize the necessary sub-hash and attach it to the original top-level hash. There are simpler hacks around that auto-initialize a hash, but they suffer from auto-vivification of hash keys (ie. looking up a hash key will create an empty hash there even without an assignment). In essence, the problem could be "solved" by monkey patching nil, though that would be the worst sort of abuse of monkey patching I can imagine. As far as checking the class is concerned, well that's just a convenient method of showing what I'm doing, I could also define a method such as is_not_defined? and check if the object at the end of the hash responds to that. The fundamental issue is that any object could be stored in the hash, so whatever I check has to be valid for any possible object. That's why I defined nil? for the UndefinedHash class even though it is a bit kludgey--it's better than monkey patching Object or NilClass.