> On Tue, Jul 26, 2011 at 4:54 PM, Greg Willits <[email protected]> wrote: >> On Jul 26, 2011, at 3:39 PM, Glenn Little wrote: >> >>> Just curious, is there a ruby best practice for effectively passing >>> parameters by value to protect them from side effects? >>> <snip> >> >>> def recurse(x = nil) >>> y = x.dup >>> y = <some processing to reflect current node> >>> self.children.each do |c| >>> c.recurse(y) >>> end >>> end >> >> >> I do it as shown above. Make the method that would otherwise do the >> mangling, responsible for NOT mangling it. IMO, putting the dup as part of >> the parameters assumes unnecessary knowledge of how the method works. If you >> change the method some day, or want the mangling, you potentially have a >> bunch of code outside the method to change. Keep it encapsulated. >> >> -- gw
On Jul 26, 2011, at 11:07 PM, Glenn Little wrote: > Although couldn't you make a case the other way around? Make the > caller rather than the callee responsible for deciding whether or not > it wants its variable mangled? Say you made the method responsible > for not mangling. There's no real precedent for assuming that about > rails methods in general, but if you did that and had outside code > relying on that, what if you later changed the method to go ahead and > mutate the parameter? Now you've still got outside, possibly > dangerous dependencies. > > Although I do get that by coding the protection in the callee, you > only have to do it once. Maybe that's enough reason. > > -glenn Re-reading my first reply, the "knowledge" argument was weak. It popped into my head as a factor, but it's a lame one--of course you have to know whether a method will mutate your inputs or not. So, scratch that particular bit. As far as precendent goes, to me, the default assumption with Ruby is pass by reference and don't mangle the inputs. Most of the code I write seems to work out that way, so I would expect a method to not mutate the input unless the name made it pretty obvious that it will. IMO, whether mangling/mutating happens should be apparent (as much as possible) by the method name. If there's just no way to express it clearly with the method name, then add the ! to make it obvious. And, yes, to me, having the mangling/not-mangling determined in one place is reason enough to put the dup inside the method in this case. That's what I was mostly after. Your preferred behavior is to not mangle, so make that happen from one place. If you really thought you'd need both versions, then rather than redundantly controlling the dup outside the method, you'd have method and method! versions of the code. -- gw -- SD Ruby mailing list [email protected] http://groups.google.com/group/sdruby
