[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Declaring instance variables dynamically

Alex Schearer

1/19/2007 5:56:00 PM

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?

--
Posted via http://www.ruby-....

15 Answers

Ryan Davis

1/19/2007 6:06:00 PM

0


On Jan 19, 2007, at 9:55 AM, Alex Schearer wrote:

> 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?

ri OpenStruct


Tim Pease

1/19/2007 6:33:00 PM

0

On 1/19/07, Ryan Davis <ryand-ruby@zenspider.com> wrote:
>
> On Jan 19, 2007, at 9:55 AM, Alex Schearer wrote:
>
> > 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?
>
> ri OpenStruct
>

http://www.ruby-doc.org/stdlib/libdoc/ostruct/rdoc/classes/OpenS...

To elucidate a little more, OpenStruct is a great class that does what
you want ...

u = OpenStuct.new
u.name = 'bob'
u.mood = 'surly'

p u.name
p u.mood

u.freeze
u.age = 59 #=> raises TypeError


Blessings,
TwP

Gary Wright

1/19/2007 7:45:00 PM

0


On Jan 19, 2007, at 12:55 PM, Alex Schearer wrote:
> 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




Alex Schearer

1/19/2007 8:05:00 PM

0

Thanks for the feedback. I am in fact trying to do what openstrtuct
allows despite any confusing language I might have employed. I was
curious whether there was any way to do so without employing a hash
table -- that isn't to say that PHP doesn't employ a hash table with its
objects. Now I know, and let me just also say thank you for the lengthy
response. I invariably find it more useful when more experienced
members of the community explain/tell me something than when they point
me to a reference document, though that is still more useful than no
response at all.


--
Posted via http://www.ruby-....

Gary Wright

1/19/2007 8:43:00 PM

0


On Jan 19, 2007, at 3:05 PM, Alex Schearer wrote:

> Thanks for the feedback. I am in fact trying to do what openstrtuct
> allows despite any confusing language I might have employed. I was
> curious whether there was any way to do so without employing a hash
> table -- that isn't to say that PHP doesn't employ a hash table
> with its
> objects. Now I know, and let me just also say thank you for the
> lengthy
> response. I invariably find it more useful when more experienced
> members of the community explain/tell me something than when they
> point
> me to a reference document, though that is still more useful than no
> response at all.

Well, it is certainly possible to roll your own class that
uses instance variables instead of the hash table. You can use
method_missing to capture calls to object.x and object.x= and then
set or get the matching instance variables.

I'll bet this has been done many times before. Maybe in facets? Trans?


Gary Wright




James Gray

1/19/2007 8:58:00 PM

0

On Jan 19, 2007, at 2:42 PM, gwtmp01@mac.com wrote:

>
> On Jan 19, 2007, at 3:05 PM, Alex Schearer wrote:
>
>> Thanks for the feedback. I am in fact trying to do what openstrtuct
>> allows despite any confusing language I might have employed. I was
>> curious whether there was any way to do so without employing a hash
>> table -- that isn't to say that PHP doesn't employ a hash table
>> with its
>> objects. Now I know, and let me just also say thank you for the
>> lengthy
>> response. I invariably find it more useful when more experienced
>> members of the community explain/tell me something than when they
>> point
>> me to a reference document, though that is still more useful than no
>> response at all.
>
> Well, it is certainly possible to roll your own class that
> uses instance variables instead of the hash table. You can use
> method_missing to capture calls to object.x and object.x= and then
> set or get the matching instance variables.
>
> I'll bet this has been done many times before. Maybe in facets?
> Trans?

It's called OpenStruct and it is included in Ruby's standard library.

James Edward Gray II


Gary Wright

1/19/2007 9:06:00 PM

0


On Jan 19, 2007, at 3:58 PM, James Edward Gray II wrote:
> It's called OpenStruct and it is included in Ruby's standard library.

The original poster wanted the setters and getters mapped to instance
variables. OpenStruct maps them to key/value pairs in an internal hash.

Gary Wright




Sam Smoot

1/19/2007 10:49:00 PM

0


Alex Schearer wrote:
> I was curious whether there was any way to do so without employing a
> hash table

Here you go:

> class User
> attr_accessor :name
> end
=> nil
> me = User.new
> me.name = 'Sam'
=> 'Sam'
> you = User.new
> you.name = 'Alex'
=> 'Alex'
> you.mood = :happy
=> NoMethodError...
> you.class.send(:attr_accessor, :mood)
> you.mood = :happy
=> :happy
> me.mood = :potato
=> :potato

So you can extend classes at run-time any number of ways, this is just
one of them. You can make it more magical with method_missing and a
combination of instance_variable_get and instance_variable_set too:

> module Magic
> def method_missing(sym, *args)
> name = sym.to_s
> if name[-1,1] == '='
> instance_variable_set("@#{name[0, name.size - 1]}", *args)
> else
> instance_variable_get("@#{name}")
> end
> end
> end
=> nil
> class Person
> include Magic
> end
=> nil
> p = Person.new
> p.name = 'Alex'
=> 'Alex'
> p.mood = :peppy
=> :peppy
> puts p.name
=> Alex

Jymesion

2/9/2014 11:43:00 PM

0

On 08 Feb 2014 01:37:00 +0100, A_Tina_Hall@kruemel.org (A. Tina Hall)
wrote:
><noreplies@jymes.com> wrote:
>> I do that in dialogue to reference things impractical/impossible to
>> show.
>
>Can't you put it in a thought instead? It's the same situation as far
>below the thought about making money which I thought interrupts the
>flow. Backround info.

He'd be thinking it, and the story is her pov.

Also, I'm adamant about not using 'tell' in narration, and thoughts
are kind of a border region between dialogue and narration.

>> It's a reference to Bilbo Baggins.
>
>Do they know that story in your story?

Could they have a similar story, in the same way that stories of a
great flood and a lone survivor come from many cultures?


>In one of my stories people keep talking about the real world (theirs),
>as opposed to the one some can view with a special talent (now and then
>implied to be ours in a hopefully obvious way).

Yeah, I got the even from that snippet you posted, and I wondered how
that plays out.

>> Mainly that it's an object of great power which whores itself out to
>> anyone who wields it.
>
>Ah. Didn't quite hit the mark then with me.

Thanks. I suspect it was one of those things that my conscious mind
was saying: we need this, and this, and this. My writing is much
better when my conscious mind shuts up.

>> I don't see it interrupting the flow. It's leading into it.
>
>But it's in the middle of the conversation!

I must have misunderstood what you meant. I was going off the 'you
want to get rich' of the first line.

>Well, insert the words 'nasty', 'sadistic', and similar somewhere in the
>description of this old guy. He laughs at naivety, and employs it to
>charm people so he can jump on them with a nasty surprise and enjoy them
>being hurt, including children. Once he did what the girl here was
>warned of he just sees her as his new toy.

The Steward in my story is sort of like that.

"What do you mean to do to us?" Alis asked, still clutching Lina's
hand.

"In truth, I am not sure. It would be easy enough to kill you." He
paused, thinking for a moment. "Too easy. Long ago I made sport of
killing brave men and drinking their blood, but like all games played
too often, it lost its thrill. Although you've shown mettle at times,
I fear your blood is too pale and weak to rekindle those fires." He
stabbed the dagger into the top of the desk. "I could lock you away in
my dungeons and gloat over your pain, but there are so many people
down there, that joy weakens every day. I am not sure what to do with
you." He smiled. When his lips parted, smoke curled around yellow
fangs. "But I can assure you it will be interesting."

JF

2/10/2014 9:41:00 AM

0

On 10/02/2014 00:38, Dorothy J Heydt wrote:

>> Is it possible for people of another time and place to have the same
>> ancient stories as we do? I'm thinking of all the religions in which a
>> flood is significant.
>
> To say nothing of the King who sacrifices himself for his people.
>
> C. S. Lewis tells the story of a thoroughgoing atheist of his
> acquaintance who once said about the Gospels, "Rum thing. All
> that stuff of Frazer's about the dying god. Rum thing. It
> almost looks as if it actually happened once."
>

A botched second coming, fillings in a million mouths. That was a
very odd one.

JF