3 ms·
I personally find the #returning method very ugly. It's an abstraction that seems completely unnecessary to me. Instead of assigning a variable and then returni
by codyrobbins 17y ago
I personally find the #returning method very ugly. It's an abstraction that seems completely unnecessary to me. Instead of assigning a variable and then returning the value, two very fundamental mechanisms in the language that are easily understood by any programmer (whether they know Ruby or not), you're bypassing them and introducing this method whose purpose I don't feel is immediately obvious.
It would be one thing if the pattern saved a lot of unnecessary code, but it doesn't. The assignment of the local variable just becomes the block variable, and you have an 'end' where the method-final return would be. Instead of a simple assignment, you now have the method invocation and the arguably more complicated block syntax.
I'll address the two particular motivations raised by the author specifically because I don't agree with either of them. First, I don't think forgetting to return the variable is a common bug. Anecdotally, I can't ever remember making this mistake myself. Even if I were to, it would be immediately obvious what the problem is. I'm open to the fact that other people perhaps make this mistake, but I'd be surprised if they routinely do. Second, I don't feel like it's obvious at all what the return value of the method is up-front, because the method invocation is confusing if you don't know what it does. Even if you do, it doesn't gain you anything you don't get by simply initializing a local at the start of the method, especially if you call the local return_value or something self-descriptive like that.
This kind of refactoring is the kind that I don't like — refactoring for the sake of refactoring, and making the code less accessible (that is, more complicated and harder to understand) for no discernible benefit.
- raganwald 17y agoI'm not sure if you are arguing with me or with Rails. Rails includes the #returning method. If you don't like using it you are entitled to your opinion. I won't argue with you, because that is not what this post is really about. I encountered bugs like forgetting to return the intialized object from a method as well as assigning to the parameter of a return invocation a number of times when working with a large Rails code base. But if you have never encountered it, you need never use #returning in any of its forms. So really, I'm not arguing with you. Different people, different experiences, different approaches to code. I like #returning, I like #let, I like a lot of things that impose block structure on code. Others do things differently with my blessing.
- codyrobbins 17y agoYeah, I know I don't have to use it. I just think the style it introduces is more abstruse overall than the problem it's solving. To answer your question, I'm mostly arguing with Rails, not you. Obviously, if it's useful to people they'll use it and who am I to declare by fiat that something's not useful to somebody else? But just because some level of personal preference is involved doesn't mean we can't try to talk about something on the basis of its objective merits. But I'm often (usually?) wrong — I was just putting in my two cents for the sake of discussion =)
- raganwald 17y agoWell then, if you want to talk, I'd say this... (elided). No, scratch that, instead I'll say this: I don't buy the argument that #returning, or SymbolToProc, or any of the other myriad (and often irritating) little idiomatic extensions to Ruby make code less complicated and more difficult to read. It's an old, old argument and tiresome to rehash, but ultimately it's a mistake to make things easier to read for someone who doesn't know the idioms at the expense of making things easier to read for somone who does know the idioms. If you feel the idiom doesn't add value, that's one thing. But I have trouble with the idea that #returning is harder to read. I personally find it easier to read because it is so obvious what is going on.
- codyrobbins 17y agoIsn't it implied and understood that I can only speak for myself and from my own perspective? I think my post was littered liberally enough with words like 'personally' and 'I feel' that it's understood I'm not trying to speak in absolutes. So, would you rather I didn't raise any questions about the relative merits of the code simply because there may be people who find it useful? I'm certainly not arguing that no one will find it useful, I'm simply saying that I don't like it and giving the reasons why I think so. If you didn't want people to discuss the relative merits of the code, why did you post it? EDIT: Ah, you elided what the above is a rebuttal of, which is good because that brings the discussion back to the actual code in question. There are a ton of little idiomatic extensions to Ruby that are immensely useful, SymbolToProc being a very good example. The presence of so many of them is one of the great things about Rails. So, I'm not arguing against such things as a whole, as you imply I am. I'm simply saying that #returning in particular is one that I have problems with. Nor am I saying that making things less readable for the uninitiated is a sufficient motivation to bar use of such things. However, this particular idiom gives you so little that I feel what you gain from it does not outweigh the cost of introducing it. So, I do feel that the idiom doesn't add any value, and for that reason there is a cost associated with its use. It doesn't save you any code, and it's more complicated than the code it replaces, which is why I am puzzled that you find it easier to understand. It makes things wordier with a block invocation when a simple assignment will suffice. Ostensibly, assignment is a much 'lower level' mechanism than invoking a method with a block. I readily admit, though, that if you find it easier to read then there's no argument I can make, because it works for you. Similarly, though, I can state that it is not easier to read for me. So, I guess we just have to agree to disagree on the basis that our brains work differently =)
- raganwald 17y agoMore discussion about this idiom, this time discussing Ruby 1.9's #tap method: http://blog.rubybestpractices.com/posts/gregory/011-tap-that-hash.html http://blog.rubybestpractices.com/posts/gregory/011-tap-that...
- luigi 17y agoAny insight as to why they chose to name it tap instead of returning? I much prefer returning.
- raganwald 17y agoThe original use cae was where you have a method chain and you want to "tap into" one of the values, e.g. foo().bar().blitz() becomes: foo().bar().tap { |b| puts b.inspect }.blitz() It takes its inspiration from Unix's "tee."