Struct creates non-standard classes


#1

If Struct is a shorthand way for creating Classes, why don’t objects
created from those Classes have instance_variables?

Struct.new ‘Car’, :make, :model, :year
c = Struct::Car.new ‘Saturn’, ‘SC2’, 1997
c.instance_variables => []
c.members => [“make”, “model”, “year”]

Note that members is an instance method of Struct, whereas
instance_variables is an instance method of Object.


#2

DÅ?a Nedeľa 12 Február 2006 20:45 Mark V. napísal:

If Struct is a shorthand way for creating Classes, why don’t objects
created from those Classes have instance_variables?

My guess is because Struct directly accesses a C hashtable, instead of
registering instance variables in the interpreter. Not like it should
matter
unless you for some reason with to access the variables with reflection
instead of the accessors, which I can’t imagine why you’d want to do.

David V.


#3

On Mon, 2006-02-13 at 04:45 +0900, Mark V. wrote:

If Struct is a shorthand way for creating Classes, why don’t objects
created from those Classes have instance_variables?

Struct.new ‘Car’, :make, :model, :year
c = Struct::Car.new ‘Saturn’, ‘SC2’, 1997
c.instance_variables => []
c.members => [“make”, “model”, “year”]

Note that members is an instance method of Struct, whereas
instance_variables is an instance method of Object.

Because they’re not stored as instance variables.


#4

On 2/12/06, David V. removed_email_address@domain.invalid wrote:

Dòa Nedeµa 12 Február 2006 20:45 Mark V. napísal:

If Struct is a shorthand way for creating Classes, why don’t objects
created from those Classes have instance_variables?

My guess is because Struct directly accesses a C hashtable, instead of
registering instance variables in the interpreter. Not like it should matter
unless you for some reason with to access the variables with reflection
instead of the accessors, which I can’t imagine why you’d want to do.

My issue is that I wanted to think of Struct as an alternate way of
defining a class and that after doing so I could use it like any other
class. However, classes created using Struct aren’t the same as
classes created in the “normal” way and because of that I have to
remember when I use them how they differ. I’ve found one way in which
they differ and don’t know if there are others.


#5

Dòa Nedeµa 12 Február 2006 21:48 Robert K. napísal:

You can.
methods) does not mean that it’s always the best thing to do.

The fact that there are instance variables is a mere detail of the
implementation. If you stick with this basic OO usage pattern and make
accessing instance variables directly the exception instead of the
rule there is no difference in using Struct created classes and
“normal” classes.

Amen.

I blame selfdot syndrome when using setters for people using instance
attributes directly. I wonder if we’re getting that shorthand I saw
mentioned
somewhere, if using accessors wasn’t any longer than not using them, I
expect
a dramatic increase of their use internally.

David V.


#6

2006/2/12, Mark V. removed_email_address@domain.invalid:

On 2/12/06, David V. removed_email_address@domain.invalid wrote:

Dòa Nedeµa 12 Február 2006 20:45 Mark V. napísal:

If Struct is a shorthand way for creating Classes, why don’t objects
created from those Classes have instance_variables?

My issue is that I wanted to think of Struct as an alternate way of
defining a class and that after doing so I could use it like any other
class.

You can.

However, classes created using Struct aren’t the same as
classes created in the “normal” way and because of that I have to
remember when I use them how they differ. I’ve found one way in which
they differ and don’t know if there are others.

IMHO you better get used to access instance variables through accessor
methods instead of directly - even inside another class. You can run
into numerous problems if you always directly access instance
variables. The fact that Ruby allows to do this (even from sub class
methods) does not mean that it’s always the best thing to do.

The fact that there are instance variables is a mere detail of the
implementation. If you stick with this basic OO usage pattern and make
accessing instance variables directly the exception instead of the
rule there is no difference in using Struct created classes and
“normal” classes.

Kind regards

robert


#7

Mark V. wrote:

On 2/12/06, David V. removed_email_address@domain.invalid wrote:> Dòa Nedeµa 12 Február 2006 20:45 Mark V. napísal:> > If Struct is a shorthand way for creating Classes, why don’t objects> > created from those Classes have instance_variables?> >>> My guess is because Struct directly accesses a C hashtable, instead of> registering instance variables in the interpreter. Not like it should matter> unless you for some reason with to access the variables with reflection> instead of the accessors, which I can’t imagine why you’d want to do.
My issue is that I wanted to think of Struct as an alternate way ofdefining a class and that after doing so I could use it like any otherclass. However, classes created using Struct aren’t the same asclasses created in the “normal” way and because of that I have toremember when I use them how they differ. I’ve found one way in whichthey differ and don’t know if there are others.
–R. Mark V.Partner, Object Computing, Inc.

I don’t know why some posts come out like the above. But anyway:

This Struct issue was one reason I created SuperStruct (see
http://sstruct.rubyforge.org).

The usual disclaimer: I think it has bugs in spite of my testing.
If you find any, let me know.

Cheers,
Hal


#8

Hal F. wrote:

other> class.

You can.

Well, what if you want to add a new method to the class? That
method should have the right to use the instance variables.

It does, if there are any.

But in a Struct there aren’t any.

Must a class have instance variables to be a ‘real’ class?

Why does the use of an array or hash, as the sole instance variable,
seem (if I’m following this correctly) to disqualify a class as a ‘real’
class?

From the outside, objects simply respond to messages. On the inside,
they do stuff when sent a message. Sometimes the outside and the inside
match up (where you get the Ruby version of public properties), but
there’s no reason they have to, and no reason to assume it is the
case.

obj.foo=x

should not lead one to think that obj implements an instance var @foo.


#9

Robert K. wrote:

2006/2/12, Mark V. removed_email_address@domain.invalid:> On 2/12/06, David V. removed_email_address@domain.invalid wrote:> > Dòa Nedeµa 12 Február 2006 20:45 Mark V. napísal:> > > If Struct is a shorthand way for creating Classes, why don’t objects> > > created from those Classes have instance_variables?

My issue is that I wanted to think of Struct as an alternate way of> defining a class and that after doing so I could use it like any other> class.

You can.

Well, what if you want to add a new method to the class? That
method should have the right to use the instance variables.
But in a Struct there aren’t any.

Hal


#10

DÅ?a Pondelok 13 Február 2006 07:14 Hal F. napísal:

Once I wanted to construct a simple class, so I used Struct. Later I
decided I wanted to add a custom method to it. I discovered then that
the attributes did not correspond to instance variables. I had to
re-write the class instead of using a Struct.

Hmm. Can you give an example where you absolutely need to access an
instance
variable instead of using the getter / setter?

David V.


#11

James B. wrote:

My issue is that I wanted to think of Struct as an alternate way of>

class?

From the outside, objects simply respond to messages. On the inside,
they do stuff when sent a message. Sometimes the outside and the inside
match up (where you get the Ruby version of public properties), but
there’s no reason they have to, and no reason to assume it is the case.

obj.foo=x

should not lead one to think that obj implements an instance var @foo.

It doesn’t have to, but it’s common practice.

Once I wanted to construct a simple class, so I used Struct. Later I
decided I wanted to add a custom method to it. I discovered then that
the attributes did not correspond to instance variables. I had to
re-write the class instead of using a Struct.

Maybe I didn’t have the “right” to expect those instance variables to
exist, but I think it’s an understandable mistake.

Hal


#12

On 2/13/06, David V. removed_email_address@domain.invalid wrote:

Dòa Pondelok 13 Február 2006 07:14 Hal F. napísal:

Once I wanted to construct a simple class, so I used Struct. Later I
decided I wanted to add a custom method to it. I discovered then that
the attributes did not correspond to instance variables. I had to
re-write the class instead of using a Struct.

Hmm. Can you give an example where you absolutely need to access an instance
variable instead of using the getter / setter?

I think the main use would be for writing tools that help Ruby
developers. For example, I might want to write a tool that inspects
Ruby objects in a running program. I might want to ask “What data does
this object hold?”. In order to answer that question, I’d have to know
whether the object was created from a “normal” class or a struct.