From: Doug Glidden <41mortimer@...> Date: 2008-09-08T23:39:19+09:00 Subject: "Pointer" to an object? (i.e. reflect changes to original) Hi, I've already made a post similar to this on the Rails list, so I apologize to anyone who subscribes to both for being repetitive. From what I've read, it seems to be impossible to create "pointers" in Ruby, such as the following pseudocode: string = 'a string' copy = *string string = 'a different string' # both string and copy are changed The only way I've found to accomplish this is the following: string = 'a string' copy = string string.replace 'a different string' # both string and copy are changed But this seems a very poor alternative, because it forces code operating on the _original string_ to know that a _copy_ of the string exists! (Heaven help us if string should be some arbitrary object instead of an actual String!) This is clearly in violation of all sorts of good programming principles. Consider the following example, which could be a very realistic usage in a Ruby address book. (Note: Person is an actual class I've implemented that is extensively self-modifying, so the code below is entirely possible. Basically, if the @foo instance variable does not exist, Person.foo= redirects to first create a new @foo instance variable and accessors for it, add it to @field_list, and assign it. Assume that Person class is a library being used here.) # code snippet 1 p = Person.new # => # p.personal_email = 'me@home.com' p.primary_email = p.personal_email # I want p.primary_email to always reflect # the contents of p.personal_email # p.inspect now produces # # code snippet 2, perhaps called by some library, who knows where p.personal_email = 'me@gmail.com' # whoops, p.primary_email is no longer the # same as p.personal_email Code snippet 2, being agnostic of the fact that we want to make a copy of p.personal_email that will reflect any reassignment of it, has unwittingly made it impossible for us to do so. Of course we could fix that, nominally, by changing the implementation of Person.foo=: class << Person def foo=(new_val) @foo.replace new_val end end But changing libraries isn't a great idea, and it still violates the principles of OO coding, because we've forced the library to reflect the way we're using it. Worse yet, what happens when either @foo or new_val is an object of a class other than String? Most likely a NameError, and as far as I can tell, no way to get around it. Now, the most elegant solution I can think of would require some pretty low-level meddling with the core of Ruby, and that would be to add some level support for pointers, but that seems to be frowned upon by Rubyists. The only other solution I can think of is to change the functionality of Object.= to act like String.replace (not creating a new copy), requiring coders to always use dup if they want to specifically specify creating a new copy. I'm pretty sure we'd all agree that would be a terrible solution. I've read a lot of "I don't think there's a realistic situation where that functionality would be needed" type of responses in past discussions of this, but I think the example I've described is pretty common and realistic. If there's a better, elegant way to allow this sort of functionality, please let me know. Thanks, Doug -- Posted via http://www.ruby-forum.com/.