Variable pointer

@c = "donal"
@b = @c

abrakadabra(@b, @c)

@c = "mickey"

print @b resulted "mickey"

Is there something like abrakadabra method in ruby? The only thing I
can think to emulate this is using global variable.

Thank you.

No. Variables aren't pointers or locations; they're labels for
objects. By changing @c you have changed its object. You haven't
changed @c.

However, you can trick it out with a Var (or Ref) object (google
around for various implementations) where you can set the value,
something like:

c = Ref.new("donald")
b = c
c._value = "mickey"
puts b

-austin

···

On 11/1/06, akbarhome <akbarhome@gmail.com> wrote:

@c = "donal"
@b = @c

abrakadabra(@b, @c)

@c = "mickey"

print @b resulted "mickey"

Is there something like abrakadabra method in ruby? The only thing I
can think to emulate this is using global variable.

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

akbarhome (akbarhome@gmail.com)
1/11/2006 16:45:17

@c = "donal"
@b = @c

abrakadabra(@b, @c)

@c = "mickey"

  ^^^^ the problem is here

In ruby, var = value is not "change var's value", but rather "set name var for value".
Then, after
@b = @c
@c and @b "points" to same value, and if you change this value, you would see new value through @b and through @c.

@c = "donal"
@b = @c
@c.upcase!
print @b #=> DONAL

but when you do
@c = "mickey"

@c becames to 'point' to "mickey", and @b - still to "donal".
AFAIK, there's no way to change @b in correspondence.

V.

HI --

@c = "donal"
@b = @c

abrakadabra(@b, @c)

@c = "mickey"

print @b resulted "mickey"

Is there something like abrakadabra method in ruby? The only thing I
can think to emulate this is using global variable.

It was recently noted on the Rails mailing list that something like
that happens in ActiveRecord. Given Person and Address models, where
Person has_one Address:

   a = person.address
   person.address = Address.find(some_other_address)
   puts a # a has changed!

I find it un-Rubyish and disconcerting (though I'm still waiting for
someone to explain the rationale; there may be something I'm missing).

I think you have to work pretty hard to get that to happen. Now and
then there's a vogue for "become", which might do something like this
(i.e., change all references), though not with assignment syntax.

David

···

On Wed, 1 Nov 2006, akbarhome wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

can you show an example? are you saying that activerecord avoids apparent
copy-on-write semantics with some trickery?

-a

···

On Thu, 2 Nov 2006 dblack@wobblini.net wrote:

It was recently noted on the Rails mailing list that something like
that happens in ActiveRecord. Given Person and Address models, where
Person has_one Address:

a = person.address
person.address = Address.find(some_other_address)
puts a # a has changed!

I find it un-Rubyish and disconcerting (though I'm still waiting for
someone to explain the rationale; there may be something I'm missing).

--
my religion is very simple. my religion is kindness. -- the dalai lama

Hi --

It was recently noted on the Rails mailing list that something like
that happens in ActiveRecord. Given Person and Address models, where
Person has_one Address:

a = person.address
person.address = Address.find(some_other_address)
puts a # a has changed!

I find it un-Rubyish and disconcerting (though I'm still waiting for
someone to explain the rationale; there may be something I'm missing).

can you show an example? are you saying that activerecord avoids apparent
copy-on-write semantics with some trickery?

Here's an example from a program which models Ideas; each Idea belongs
to a Page.

i = Idea.find(6)

=> #<Idea:0xb79eec2c @attributes={"page_id"=>"6", "id"=>"6",
"content"=>"Go to Paris"}>

# Save the idea's page in p

p = i.page

=> #<Page:0xb79e4a88 @attributes={"scratchpad_id"=>"6",
"title"=>"Domestic travel", "id"=>"6"}>

# Change the idea's page to a different one

i.page = Page.find(7)

=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

# Examine the saved page -- it's the new one

p

=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

I don't know the rationale. When I (think I'm) assign(ing) an object
to a variable, I really don't want it to turn out that it's some
special arrangement whereby the variable is subject to reassignment
without notice. I expect:

   p = i.page

to be exactly equivalent to:

   p = Idea.find(i.page.id)

with respect to p.

David

···

On Thu, 2 Nov 2006, ara.t.howard@noaa.gov wrote:

On Thu, 2 Nov 2006 dblack@wobblini.net wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

holy cow that is pure evil!

thanks for the example david.

-a

···

On Thu, 2 Nov 2006 dblack@wobblini.net wrote:

I don't know the rationale. When I (think I'm) assign(ing) an object to a
variable, I really don't want it to turn out that it's some special
arrangement whereby the variable is subject to reassignment without notice.
I expect:

p = i.page

to be exactly equivalent to:

p = Idea.find(i.page.id)

with respect to p.

--
my religion is very simple. my religion is kindness. -- the dalai lama

I must be missing something. Isn't this how virtually all Ruby code works?

class Foo
  attr_accessor :bar
end

f = Foo.new
f.bar = "some_string"

p = f.bar
f.bar << " and how!"
puts p

What makes the Rails version of this unexpected?

···

On 11/1/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

Hi --

On Thu, 2 Nov 2006, ara.t.howard@noaa.gov wrote:

> On Thu, 2 Nov 2006 dblack@wobblini.net wrote:
>
>> It was recently noted on the Rails mailing list that something like
>> that happens in ActiveRecord. Given Person and Address models, where
>> Person has_one Address:
>>
>> a = person.address
>> person.address = Address.find(some_other_address)
>> puts a # a has changed!
>>
>> I find it un-Rubyish and disconcerting (though I'm still waiting for
>> someone to explain the rationale; there may be something I'm missing).
>
> can you show an example? are you saying that activerecord avoids apparent
> copy-on-write semantics with some trickery?

Here's an example from a program which models Ideas; each Idea belongs
to a Page.

>> i = Idea.find(6)
=> #<Idea:0xb79eec2c @attributes={"page_id"=>"6", "id"=>"6",
"content"=>"Go to Paris"}>

# Save the idea's page in p
>> p = i.page
=> #<Page:0xb79e4a88 @attributes={"scratchpad_id"=>"6",
"title"=>"Domestic travel", "id"=>"6"}>

# Change the idea's page to a different one
>> i.page = Page.find(7)
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

# Examine the saved page -- it's the new one
>> p
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

I don't know the rationale. When I (think I'm) assign(ing) an object
to a variable, I really don't want it to turn out that it's some
special arrangement whereby the variable is subject to reassignment
without notice. I expect:

   p = i.page

to be exactly equivalent to:

   p = Idea.find(i.page.id)

with respect to p.

Yikes! How is this even possible? Somehow the method is changing the
variable bindings in its caller. Is this related to Binding.of_caller
(which exploited a bug in 1.8.4 and broke when the bug was fixed in
1.8.5 - see
<URL:http://eigenclass.org/hiki.rb?breakpoint+breaking+in+1.8.5&gt;\)?

Jeremy Henty

···

On 2006-11-01, dblack@wobblini.net <dblack@wobblini.net> wrote:

Here's an example from a program which models Ideas; each Idea belongs
to a Page.

i = Idea.find(6)

=> #<Idea:0xb79eec2c @attributes={"page_id"=>"6", "id"=>"6",
"content"=>"Go to Paris"}>

# Save the idea's page in p

p = i.page

=> #<Page:0xb79e4a88 @attributes={"scratchpad_id"=>"6",
"title"=>"Domestic travel", "id"=>"6"}>

# Change the idea's page to a different one

i.page = Page.find(7)

=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

# Examine the saved page -- it's the new one

p

=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

Wow, that looks nasty. Can you point me to the releveant thread in
the rails group where this was discussed?

- Rob

···

On 11/1/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

Hi --

On Thu, 2 Nov 2006, ara.t.howard@noaa.gov wrote:

> On Thu, 2 Nov 2006 dblack@wobblini.net wrote:
>
>> It was recently noted on the Rails mailing list that something like
>> that happens in ActiveRecord. Given Person and Address models, where
>> Person has_one Address:
>>
>> a = person.address
>> person.address = Address.find(some_other_address)
>> puts a # a has changed!
>>
>> I find it un-Rubyish and disconcerting (though I'm still waiting for
>> someone to explain the rationale; there may be something I'm missing).
>
> can you show an example? are you saying that activerecord avoids apparent
> copy-on-write semantics with some trickery?

Here's an example from a program which models Ideas; each Idea belongs
to a Page.

>> i = Idea.find(6)
=> #<Idea:0xb79eec2c @attributes={"page_id"=>"6", "id"=>"6",
"content"=>"Go to Paris"}>

# Save the idea's page in p
>> p = i.page
=> #<Page:0xb79e4a88 @attributes={"scratchpad_id"=>"6",
"title"=>"Domestic travel", "id"=>"6"}>

# Change the idea's page to a different one
>> i.page = Page.find(7)
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

# Examine the saved page -- it's the new one
>> p
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

I don't know the rationale. When I (think I'm) assign(ing) an object
to a variable, I really don't want it to turn out that it's some
special arrangement whereby the variable is subject to reassignment
without notice. I expect:

   p = i.page

to be exactly equivalent to:

   p = Idea.find(i.page.id)

with respect to p.

--

Change that line to:

   f.bar = "new string"

James Edward Gray II

···

On Nov 1, 2006, at 10:07 AM, Wilson Bilkovich wrote:

f.bar << " and how!"

Hi --

Hi --

>
>> It was recently noted on the Rails mailing list that something like
>> that happens in ActiveRecord. Given Person and Address models, where
>> Person has_one Address:
>>
>> a = person.address
>> person.address = Address.find(some_other_address)
>> puts a # a has changed!
>>
>> I find it un-Rubyish and disconcerting (though I'm still waiting for
>> someone to explain the rationale; there may be something I'm missing).
>
> can you show an example? are you saying that activerecord avoids apparent
> copy-on-write semantics with some trickery?

Here's an example from a program which models Ideas; each Idea belongs
to a Page.

>> i = Idea.find(6)
=> #<Idea:0xb79eec2c @attributes={"page_id"=>"6", "id"=>"6",
"content"=>"Go to Paris"}>

# Save the idea's page in p
>> p = i.page
=> #<Page:0xb79e4a88 @attributes={"scratchpad_id"=>"6",
"title"=>"Domestic travel", "id"=>"6"}>

# Change the idea's page to a different one
>> i.page = Page.find(7)
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

# Examine the saved page -- it's the new one
>> p
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

I don't know the rationale. When I (think I'm) assign(ing) an object
to a variable, I really don't want it to turn out that it's some
special arrangement whereby the variable is subject to reassignment
without notice. I expect:

   p = i.page

to be exactly equivalent to:

   p = Idea.find(i.page.id)

with respect to p.

I must be missing something. Isn't this how virtually all Ruby code works?

class Foo
attr_accessor :bar
end

f = Foo.new
f.bar = "some_string"

p = f.bar
f.bar << " and how!"
puts p

What makes the Rails version of this unexpected?

I'm not modifying an object in place, though; I'm doing a new
assignment. Or at least that's what it appears to be:

   i.page = Page.find(7)

So it's more like:

   a = "str"
   b = a
   a = "new str"
   puts b # new str

I (strongly) believe that the assignment-like syntax should not be
rigged to do this.

David

···

On Thu, 2 Nov 2006, Wilson Bilkovich wrote:

On 11/1/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

On Thu, 2 Nov 2006, ara.t.howard@noaa.gov wrote:
> On Thu, 2 Nov 2006 dblack@wobblini.net wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Hi --

···

On Thu, 2 Nov 2006, Rob Sanheim wrote:

Wow, that looks nasty. Can you point me to the releveant thread in
the rails group where this was discussed?

It's called: belongs_to nonintuitive results with assignment?

David

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Hi --

>
>> It was recently noted on the Rails mailing list that something like
>> that happens in ActiveRecord. Given Person and Address models, where
>> Person has_one Address:
>>
>> a = person.address
>> person.address = Address.find(some_other_address)
>> puts a # a has changed!
>>
>> I find it un-Rubyish and disconcerting (though I'm still waiting for
>> someone to explain the rationale; there may be something I'm missing).
>
> can you show an example? are you saying that activerecord avoids apparent
> copy-on-write semantics with some trickery?

Here's an example from a program which models Ideas; each Idea belongs
to a Page.

>> i = Idea.find(6)
=> #<Idea:0xb79eec2c @attributes={"page_id"=>"6", "id"=>"6",
"content"=>"Go to Paris"}>

# Save the idea's page in p
>> p = i.page
=> #<Page:0xb79e4a88 @attributes={"scratchpad_id"=>"6",
"title"=>"Domestic travel", "id"=>"6"}>

# Change the idea's page to a different one
>> i.page = Page.find(7)
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

# Examine the saved page -- it's the new one
>> p
=> #<Page:0xb79d1b18 @attributes={"scratchpad_id"=>"1",
"title"=>"Foreign travel", "id"=>"7"}>

I don't know the rationale. When I (think I'm) assign(ing) an object
to a variable, I really don't want it to turn out that it's some
special arrangement whereby the variable is subject to reassignment
without notice. I expect:

   p = i.page

to be exactly equivalent to:

   p = Idea.find(i.page.id)

with respect to p.

Wow, that looks nasty. Can you point me to the releveant thread in
the rails group where this was discussed?

- Rob

--
http://www.robsanheim.com
http://www.seekingalpha.com
http://www.ajaxian.com

Why is this so hard to understand? Rails isn't really doing anything magic or really even tricky here -- just "unexpected".

You are just confusing references and objects.

>> require 'ostruct'
=> true
>> o = OpenStruct.new('page' => "original", 'cover' => "hard")
=> #<OpenStruct cover="hard", page="original">
>> p = o.page
=> "original"

No surprise there. Let's change the contents of the page.

>> o.page.replace("forgery")
=> "forgery"

...and check in with our variable (aka, object reference):

>> p
=> "forgery"

Yup. Still refers to the same String object as o.page. Now let's do an assignment:

>> o.page = "restoration"
=> "restoration"
>> p
=> "forgery"

o.page now refers to a new object. But o.page = "restoration" is really just sugar for o.page=("restoration"), right?

>> def o.page=(kind); self.page.replace(kind); end
=> nil

Make p refer to the same String object as o.page again:

>> p = o.page
=> "restoration"
>> p
=> "restoration"
>> o.page
=> "restoration"

Now this "assignment" calls the newly defined page= method:

>> o.page = "imitation"
=> "imitation"
>> p
=> "imitation"
>> p.replace("faux")
=> "faux"
>> o.page
=> "faux"

So the way that variables are references to objects and the syntactic sugar that makes 'o.page = foo' look like assignment even though it's sending foo to the page= method of the o object are just colliding in your brain.

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Nov 2, 2006, at 8:55 AM, Rob Sanheim wrote:

On 11/1/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

On Thu, 2 Nov 2006, ara.t.howard@noaa.gov wrote:
> On Thu, 2 Nov 2006 dblack@wobblini.net wrote:

I had to do a double-take as well, so here's an example for the rest of
us newbies trying to follow the discussion.

Presume the following:

address = Struct.new(:street).new("Main")
address2 = Struct.new(:street).new("Oak")
person = Struct.new(:address).new(address)

Okay, now let's execute exactly the code being discussed:

[1]

a = person.address
person.address = address2
p a # Main

So assigning directly to person's address didn't change "a".

OTOH:

[2]

a = person.address
person.address.street = "Oak"
puts a.street # => Oak

So I think what's unexpected is that, in the RoR example, [1] behaves as
if it had been [2]. m.

···

Wilson Bilkovich <wilsonb@gmail.com> wrote:

On Thu, 2 Nov 2006 dblack@wobblini.net wrote:
> a = person.address
> person.address = Address.find(some_other_address)
> puts a # a has changed!

I must be missing something. Isn't this how virtually all Ruby code works?

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Tiger - http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

Hi --

Why is this so hard to understand? Rails isn't really doing anything magic or really even tricky here -- just "unexpected".

You are just confusing references and objects.

No, that's not what's going on. ActiveRecord is doing something quite
tricky.

require 'ostruct'

=> true

o = OpenStruct.new('page' => "original", 'cover' => "hard")

=> #<OpenStruct cover="hard", page="original">

p = o.page

=> "original"

No surprise there. Let's change the contents of the page.

o.page.replace("forgery")

=> "forgery"

There's nothing analogous to this in the ActiveRecord example.

...and check in with our variable (aka, object reference):

p

=> "forgery"

Yup. Still refers to the same String object as o.page. Now let's do an assignment:

o.page = "restoration"

=> "restoration"

p

=> "forgery"

o.page now refers to a new object. But o.page = "restoration" is really just sugar for o.page=("restoration"), right?

That's where ActiveRecord, in the equivalent operation, does something
very different. Imagine that when you examined p, you got
"restoration". That would be the same as was AR is doing.

def o.page=(kind); self.page.replace(kind); end

=> nil

Make p refer to the same String object as o.page again:

p = o.page

=> "restoration"

p

=> "restoration"

o.page

=> "restoration"

Now this "assignment" calls the newly defined page= method:

o.page = "imitation"

=> "imitation"

p

=> "imitation"

p.replace("faux")

=> "faux"

o.page

=> "faux"

So the way that variables are references to objects and the syntactic sugar that makes 'o.page = foo' look like assignment even though it's sending foo to the page= method of the o object are just colliding in your brain.

I'm not sure why you have to express this in terms of confusion on the
part of the people who don't like it. I think we're all well aware of
=-terminated methods and all the rest of it. So let's leave the
editorials about people's brains out of it.

Anyway.... No one is saying that you *can't* do this in Ruby, only
that what AR does is unexpected, unidiomatic, and inconsistent. The
= syntactic sugar does, indeed, allow you to write arbitrary methods:

   class C
     def thing=(n)
       puts "Ha ha!"
     end
   end

but the reason the sugar exists is to make assignment-like things look
like assignments. The thing that AR does is not assignment-like, in
any traditional or idiomatic sense. Yes, you *can* do a
non-assignment-based operation (like String#replace) in a =-method...
but, at the risk of sounding old-fashioned, I simply think that here:

   old_thing = obj.thing
   obj.thing = Thing.create

it's reasonable to expect old_thing to refer to the original
obj.thing, and not the new one. In ActiveRecord, that's not what
happens.

It's not an object-vs.-reference thing, either. There's a class
called ActiveRecord::Associations::AssociationProxy which, I believe,
is responsible for the way this works. old_thing is a proxy to
obj.thing. If you assign it differently:

   old_thing = Thing.find(obj.thing.id)
   obj.thing = Thing.create

old_thing does not change, because the proxy class is not involved.
All of this is on top of the usual object/reference stuff in Ruby; in
fact, it's a kind of super-reference that's being created (which is
precisely *not* the model that Ruby is built on -- pointers to
pointers, so to speak -- though as I've said the issue is not whether
or not it can be done).

As I've said before, if there's a rationale for AR doing it the way it
does (other than the fact that it's possible to do it that way, which
I doubt is what lies behind it), I would of course be very interested
in hearing it.

David

···

On Thu, 2 Nov 2006, Rob Biedenharn wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

This is the issue. I understand how assignment methods work, really I
do =). I just don't see a reason for this and would assume the
implementation is the simplest thing unless we _really_ need to change
that object in place. I would normally think this is just an
assignment, unless there were good optimization reasons to do
otherwise.

def o.page=(str); self.page = str; end

# or more typically w/i the class def somewhere

attr_accessor :page
def initialize
   @page = nil
end

Not sure why Rails would do an .replace instead, but maybe there are
good performance reasons relating to ActiveRecord...

- Rob

···

On 11/2/06, Rob Biedenharn <Rob@agileconsultingllc.com> wrote:

Why is this so hard to understand? Rails isn't really doing anything
magic or really even tricky here -- just "unexpected".

You are just confusing references and objects.

>> require 'ostruct'
=> true
>> o = OpenStruct.new('page' => "original", 'cover' => "hard")
=> #<OpenStruct cover="hard", page="original">
>> p = o.page
=> "original"

No surprise there. Let's change the contents of the page.

>> o.page.replace("forgery")
=> "forgery"

...and check in with our variable (aka, object reference):

>> p
=> "forgery"

Yup. Still refers to the same String object as o.page. Now let's do
an assignment:

>> o.page = "restoration"
=> "restoration"
>> p
=> "forgery"

o.page now refers to a new object. But o.page = "restoration" is
really just sugar for o.page=("restoration"), right?

>> def o.page=(kind); self.page.replace(kind); end
=> nil

--

http://www.ajaxian.com