From: Robert Klemme Date: 2005-05-07T16:59:24+09:00 Subject: Re: object reference handle (like perl's reference to scalar) "Dave Burt" schrieb im Newsbeitrag news:am_ee.5577$31.897@news-server.bigpond.net.au... > "Austin Ziegler" conversed: >> On 5/6/05, Dave Burt wrote: >>> Surely it's >>> entirely conceivable to have a reference object whose only >>> difference from the referenced object is that it responds to deref >>> and deref=? >> >> I don't recall the problems mentioned, but Ref objects have been >> mentioned in the past as problems. If anything does a class-based >> check, then the Ref object will never have a chance (and, yes, I do >> this in PDF::Writer some; not much, but some). More to the point, I >> was looking at the CSV code the other day to help someone and we >> saw: >> >> case foo >> when String >> when IO >> when ... >> end >> >> (1) It doesn't work with StringIO. (2) It can't/won't work with a >> Ref object, because you'd need to redefine Class#=== (or is it >> Module#===) to get this to work right. > > That's not even difficult. > > class Ref > def kind_of?(mod) __getobj__.kind_of?(mod) end > end > class Module > def ===(other) other.kind_of? self end > end > > My Ref module at http://www.dave.burt.id.au/ruby/ref.rb now tries to > behave as much like the referred-to object as possible. You above Module > case statement will work with Refs now, as will uses of respond_to? is_a? > kind_of? and class. A Ref will additionally respond_to a few unique > methods (ie deref, deref=). Hm, and what do you do if you have to test for Ref objects? >>>> (There's one case that I have in PDF::Writer where such a >>>> reference would be mildly useful... >> >> It's a purity problem. Right now, when you render a SimpleTable, it >> makes some modifications to bits of the data in the SimpleTable. >> This makes it very fragile. You cannot write the same SimpleTable to >> two different PDF files at the same time, because of this. If you >> render a SimpleTable, you may get a slightly different result if you >> render it again. >> >> I've got a (broken) reimplementation that separate out these >> variables into a RenderVars object (it could as well be an >> OpenStruct, but this also lets me pull some methods out of >> SimpleTable that are really only related to the RenderVars). Doing >> this will let me get around the problem of calls like: >> >> _y, _height = __table_column_headings(_y, @data) >> >> It's that place where a ref-object might be useful -- I update _y in >> place rather than by reassignment at the end. But it's a small thing >> in comparison to everything else that I do. > > Obviously an OpenStruct (or even an Array) could do the job, but why not > try a Ref? It's see-through! (Except for assignment, you have to do > ref.deref=) Of course, it's not much different from a Struct.new(:deref). I didn't follow this thread thoroughly, all I can say is that I personally haven't missed refs in Ruby until now. There are certainly things that speak in favour of your concept. But there are also problems. Ironically some of them seem to be caused by the fact that you make a Ref behave like the original instance as much as possible. That way Ref usage is more implicit than explicit and this can lead to confusion or subtle errors due to aliasing (i.e. you think you got a copy of something and modify it and some other piece of code breaks because it was just a ref). It still might be worthwile, I just get the feeling that people try to stuff things from other programming languages into Ruby because they found them cute / useful / the only way to solve certain things in that language. IMHO programming languages are different for a reason and often it's much better to adhere to the old saying "when in Rome do as the Romans do"... :-) Kind regards robert