Coming from PHP I want to take a class say,
class User
@name
end
And call it:
u = User.new
And then add a second class variable previously not declared:
u.mood = "happy"
PHP being what it is, it let you declare public class variables in
that
manner. Is there a way to acheive the same in Ruby?
It is a bit hard to sort out what you are really after because your
example and description don't really match at all with Ruby concepts.
In your example, @name is an instance variable associated with
the object User, which is an instance of Class. You aren't
actually declaring that variable but simply referencing it. In Ruby
instance variables come into existence when they are referenced, they
do not have to be declared ahead of time. In any case, using @name
within a class block like this doesn't imply anything about
variables associated with instances of User. @name is an instance
variable associated with the class itself, which in many other
languages would be called a 'class variable' but not in Ruby. In Ruby,
'class instance variable' is a very different thing than
'class variable'.
You then create an new instance of User and suggest that
you would like to be able to call 'u.mood = "happy"', which would
typically be an assignment to the instance variable @mood associated
with 'u'. This @mood is very different than @name and neither of
them are Ruby 'class variables', which are different beasts altogether.
If what you are really trying to do is have instances of User with
two attributes (instance variables) of @name and @mood, then you want
something like:
class User
attr_accessor :name
attr_accessor :mood
end
allowing you to do things like:
u = User.new
u.name = 'bob' # modifies @name associated with u
u.mood = 'happy' # modifies @mood associated with u
There are no class variables involved in this situation nor are there
any class instance variables.
If you don't even want to bother with the attr_accessor calls you can
then use the OpenStruct class as described in the other posts. Note,
OpenStruct simulates setter and getter methods for arbitrary attributes
but it doesn't actually store the data in instance variables. Instead
it uses an internal hash table:
require 'ostruct'
user = OpenStruct.new
user.name = "bob"
user.mood = "happy"
p user.instance_variables # ["@table"]
p user.instance_variable_get('@table') # {:name=>"bob", :mood=>"happy"}
Gary Wright