4 ms·
So what's the alternative?
by charlesju 18y ago
So what's the alternative?
- mdasen 18y agoWell, the alternative could be more like Python. Python supports both object methods and functions. Ruby only supports object methods. However, Ruby does allow you to define methods outside of an object - these become methods of the Object class. As such, any methods defined like functions become changes to all objects since they inherit from Object. Python is also very explicit about its namespacing and imports. In Python, you should always be able to know where any name you're using is coming from. In the example from the article, 'to_yaml' is added by requiring rubygems. That isn't so apparent (in the way that 'gem' being added by requiring rubygems would be apparent). Names are reused all the time. Names sometimes aren't related to their package in an apparent way. With Python, you have three options (one of which Python programmers will flog you for): from package import name, name2 import package from package import * -- should really only be used in an interactive python shell and not in programs In the first one, you could then call name(something) or name2(something). BUT you can see exactly where those names are coming from -- package. Unlike to_yaml which could come from wherever, it's explicit that it comes from 'package'. In the second one, you can do package.name(something) and the like. Similarly, you can see that it comes from 'package'. Ruby is really flexible, but I would argue that the author is correct in assessing that the ability to modify all objects implicitly is a bad thing.
- timr 18y agoAlso, information hiding is rumored to be important in real software. Ruby gives you the ability to nominally "hide" data, but it's trivially easy for any later programmer to violate the encapsulation. It's DHINO programming -- Data Hiding In Name Only. Not only isn't this considered a bad idea in the Ruby world, but it's actually a common technique. Use a third-party library, and you may well be re-writing core parts of the language. Sound good? You can't prevent it. I like parts of Ruby; it's a fun language. But the author is right -- it's not a language for large projects, or projects with more than a few programmers. My alternative to Ruby would allow the fast-and-loose stuff that makes Ruby fun, but also give you a way to make classes immutable and guarantee data-hiding and encapsulation when you need to do real software engineering.
- davidw 18y agoI don't like the "real software engineering is big heavy Java projects" thing (aka "bondage and discipline"). Plenty of "real software engineering" has been done to great effect with dynamic languages. Here's a random idea: rather than strict locks, perhaps transparency would be a good approach. Load up a third party library, and you get informed that it's fiddling with things, and can then find out what. Maybe it really does need to fiddle with things. Or maybe in a given situation, fiddling with things is the most efficient way of accomplishing something.
- aaronblohowiak 18y agoYea, it is fairly trivial to enable logging every time a method is overridden or added to any class in ruby. Dynamic code inspection like in JavaScript would be pretty cool, too.
- timr 18y ago"rather than strict locks, perhaps transparency would be a good approach" Transparency is a great, but you still need rules when you're working with any code that's bigger than what you can hold in your head at any given time. Doubly so when you're working with a team. Programming in a team is hard in the same way that taking care of a room full of toddlers is hard -- obviously, you want everything out in the open, but you also want to hide the sharp objects, put caps over things that can shock, and otherwise make the big, transparent room as soft and bouncy as possible. You need locks on the cabinets full of poisonous chemicals. Obviously, the locks need to be open-able, but only in special situations, and certainly not by nosy toddlers. (Before you criticize me for being paternalistic, realize that I include myself in the "toddler" category. I much prefer code that's written in a defensive style, because it's easier for me to maintain later on -- and that's where any programmer spends the majority of his time. I've developed this attitude because I know that I'm stupid, not because I'm arrogant.)
- Xichekolas 18y agoWhile I agree that writing code defensively is the way to go when a team is involved and/or you plan to have to maintain the code for years, I don't think it's the language's job to take away all the 'sharp objects'. Programmers should be smart enough to know what is sharp and how to avoid it when needed, and they should collaborate enough that no one can sneak through sloppy code. I'd rather have the ability to do certain things and rarely use it than not have the ability at all. If other programmers are constantly doing really dumb things, don't use their code in your projects.
- siong1987 18y agoDon't care about the alternative. Just use whatever you are good at. Don't get into this endless programming languages war.
- bluishgreen 18y agoNo, its not an endless war. Use Python.
- mechanical_fish 18y agoIs there a tool here, begging to be written? Why can't I point to a Ruby object and ask it "Hey, where did that method come from? Which file/method/object defined that? Which were the last three files/methods/objects to redefine that?" Obviously, you wouldn't want to enable this feature on a production server. But it might be a useful debugging tool. Worth a try, anyway. Such a thing would only help in tracking down problems. It wouldn't resolve the larger problems of, e.g., namespace collision. ("Oops, library foo and library bar both tried to define an Object.stupify() method!"), though it might make such issues easier to detect. And it would be quite easy to write perverse programs that would defeat my proposed debugger thingy, or even cause it to melt. ("My program uses singletons to dynamically redefine methods on other singletons.") But you could perhaps mitigate the latter by restricting this tool to monitoring Ruby's built in classes, and/or whatever classes the user specifically chooses to aim it at. Moreover, if a piece of Ruby code did cause the metaprogramming-tracker to dump core, that fact might serve as a valuable code smell of its own.
- ruby_roo 18y agoHeh. Oddly, the solution to convoluted monkeypatching might be monkeypatching itself. Any reason why you couldn't extend the Object class to have this self-knowledge? Or couldn't a library be required at program start that works like Perl's 'use strict;', keeping you on the straight and narrow and not falling into the tempting trap of extending classes when you shouldn't be?
- mechanical_fish 18y agothe solution to convoluted monkeypatching might be monkeypatching itself Yes, the very same thought occurred to me. Set a monkey to catch a monkey! I didn't suggest it myself, because I've been away from Ruby just long enough that I didn't remember whether one could accomplish this in pure Ruby, or if one would have to ascend up a level and do it in the interpreter.
- catch23 18y agoyeah, it's possible in pure ruby. You can do stuff to prevent monkey patching, as well as do stuff to make it easier for future monkey patchers. I prefer libraries to not do either, to make code easier to use.