3

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

jimeh
  • 1,391
  • 1
  • 16
  • 32

4 Answers4

7

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
  • 14,535
  • 3
  • 29
  • 30
  • 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 Jan 20 '09 at 10:20
  • Agreed. Thanks for the precision. – Keltia Jan 20 '09 at 10:22
  • 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 Jan 20 '09 at 13:03
  • 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 Jan 20 '09 at 14:10
  • 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 Jan 20 '09 at 16:23
3

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
  • 54,010
  • 13
  • 102
  • 111
2

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
  • 15,506
  • 7
  • 54
  • 62
1

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

Georg Schölly
  • 124,188
  • 49
  • 220
  • 267