From: SonOfLilit Date: 2007-05-30T20:25:54+09:00 Subject: Re: Introducing the "it" keyword Hi all, That is a very interesting and educating discussion :) Lately, I came up with #dump!. What is #dump, you ask? It is a solution to my problem with #p : Let's say that I have the line of code: v = matrix*Vector[1, 1, function(a)] + vector.invert Now, let's say that I think I have a bug in there. Normally, if I'm not into using a debugger (perhaps because that's in an inner loop and I want to filter the one buggy run from among 1000), I am forced to do this: f_a = function(a) v_i = vector.invert m_v = matrix * Vector[1, 1, f_a] v = m_v + v_i p "debug:", f_a, v_i, m_v, v and of course, after I'm done, re-structure the code because it's an ugly way of doing things in a language that doesn't use polish notation. Here's my solution: module Kernel def dump!(message = nil) print " ::: #{caller[1]} ::: " print "#message} ::: " if message puts self.inspect # well, actually I use #to_yaml return self end and lo!: v = matrix*Vector[1, 1, function(a).dump!("debugging that v bug")].dump! + vector.invert.dump! v.dump! # I could put it in the prev line with parens, but that's ugly no restructuring needed. This can go anywhere. And in the less messy cases, I don't even need to remove those dump! calls, I can just redefine dump! to return self silently. That, IMHO, is "the Ruby Way". In the same code that made me implement that, I've had many cases that call for "it", and used the simpler techniques in this thread to overcome it (placing "(a == stuff) and rest_of_expression" within an if, using a temp var, etc'). Here's what I'm gonna do now: module Kernel def it! $sonoflilit_it = self end def it $sonoflilit_it end end return it if (heavy_calc(param, param2, param3.moreheavylifting(param4)).it! or it.print if matrix.inverse.it!.is_what_i_want nil.it! There still is the problem of garbage collection. nil.it! solves it manually in those critical cases, like it being a large matrix. An alternative version would be: module Kernel def it!(key = :it_secret_default_key) $sonoflilit_its[key] = self end def it(key = :it_secret_default_key) $sonoflilit_its[key] end def pop_it(key = :it_secret_default_key) $sonoflilit_its.delete(key) # notice that it returns it. might be useful end def clean_its $sonoflilit_its.clean end end for cases like: if a.calculation.it!(:a).abs > b.calculation2.it!(:b).real_part puts it(:a).det else puts func(it(:b)) end clean_its While previous examples work without change (though the idiom of nil.it! isn't recommended for the nil.it(:sym) case, since the hash will still keep a member there and with time it could become memory consuming). This is not a general solution, and might look bad to some, but it serves me well. Feel free to paste it into your own project. Aur Saraf On 5/30/07, Charles Oliver Nutter wrote: > dblack@wobblini.net wrote: > > The argument from precedent is tricky, though. I'd say the presence > > of $_ and $~ and friends suggests, not that more local globals are > > desireable, but that Ruby has reached, and perhaps exceeded, its quota > > of them :-) > > No argument from me :) > > I still think "it" is a terrible keyword to introduce though. > > - Charlie > >