views:

171

answers:

4

In PHP, you can make two variables point to the same data.

$a = 'foo';
$b = 'bar';
$a =& $b;
echo $a // Outputs: bar
echo $b // Outputs: bar

What we are trying to do in Ruby is set @app_session to be equal to session[@current_app[:uid]]. So we only have to deal with @app_session in our app, and everything is automatically saved to the session.

Is there a way to do this in Ruby? After 15 minutes of reading, googling, and asking around here at the office, we're still lost... lol

+1  A: 

Isn't this the default for all ruby objects? It wouldn't make sense to copy an object every time.

Georg
+7  A: 

All variables in Ruby are references to an object.

a = b

means that a and b point to the same object. That's why when you want to copy a given object, you need to write

a = b.dup

Writing

@app_session = session[@current_app[:uid]]

points to the same object so you should be fine.

EDIT: you can verify this this way:

irb(main):001:0> a = 1
=> 1
irb(main):002:0> b = a
=> 1
irb(main):004:0> p a.object_id
3
=> nil
irb(main):005:0> p b.object_id
3
Keltia
Be aware that b.dup is a shallow copy. You can use a = Marshal.load(Marshal.dump(b)) for a deep copy.
Jonas Elfström
Agreed. Thanks for the precision.
Keltia
Don't forget Object#clone, which is slightly different. Quoting from Pickaxe: "While `clone` is used to duplicate an object, `dup` is typically uses the class of the descendent object to create the new instance." Errr, FWIW.
Mike Woodhouse
You might want to change your example to use something different than Fixnums, like Strings: Fixnums, true, false, nil and symbols are immediate values which *always* have the same object_id. So, if you changed e.g. b=a to b=1 you would still get the same result.
Jörg W Mittag
Thanks for all the help :)I'm still pretty new to Ruby, and no one at work is a Ruby-God yet... lol`@app_session = session[@current_app[:uid]]` worked just like a charm. I didn't try it, cause in PHP world where I'm from there'd be no point in even trying... lol :)
jimeh
dup is not required
Ryan Bigg
+3  A: 

Variables and constants are pointers to memory locations. Ruby does this by defaut, so you don't have to "emulate" the PVP behaviour by hand. Evidence:

a = "hi"
b = a
a.upcase!
puts a
# => "HI"
puts b
# => "HI"

As for your @app_session question, I'd do something like this:

class ApplicationController < ActionController::Base
  def app_session
    session[@current_app[:uid]]
  end
end

This lets you call the method 'app_session', so that you can easily change the implementation later on. (Say, if you find out that you need to use a constant instead of an instance variable, or whatever.)

August Lilleaas
+2  A: 

Agree with leethal and Keltia. Just one thing to point out:

When you assign some string to a variable, you ALWAYS create a new String object, by doing so.

a = "foo"  # Create a new String object and make a refer this object.
b = "bar"  # Create a new String object and make b refer this object.
a = b      # Make b refer the object created in the first step.
a = "blah" # Create a new String object and make a refer this object. (!)
puts b     # But(!) b is still "foo", because it still refers the "foo" object.
# => "foo"
Milan Novota