Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Structs and Record Types
Index -> Programming, Ruby -> Ruby Tutorials
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
wtd




PostPosted: Sun Aug 07, 2005 2:57 pm   Post subject: Structs and Record Types

Why would we want these?

There are times as you're programming when you'll want to group two or more pieces of related data together to create a single complex "thing". By grouping this data together you avoid having it stored in multiple variables, and having to pass those around separately.

An example

Say you're writing a very simple RPG. Now, to represent a character you give it a name, a race, and attack, defense, movement, and health ratings. So, we could create a particular chatacter as:

code:
moglen_the_treacherous_lawn_gnome_name = "Moglen"
moglen_the_treacherous_lawn_gnome_race = "Gnome"
# yada yada


So now let's assume we have a method which prints out the info on a character.

code:
print_character_info(moglen_the_treacherous_lawn_gnome_name,
   moglen_the_treacherous_lawn_gnome_race,
   moglen_the_treacherous_lawn_gnome_attack,
   moglen_the_treacherous_lawn_gnome_defense,
   moglen_the_treacherous_lawn_gnome_movement,
   moglen_the_treacherous_lawn_gnome_health)


Wow that's tedious!

Instead, what if we had a single variable that held all of Moglen's info?

A better way, and the freedom to go halfway

In Ruby this is where we'd use a class and objects. With objects we avoid having direct access to the variables contained within. Rather we hide them, and only allow the programmer to manipulate them though carefully defined methods. This is a sensible precaution.

Of course, Ruby is flexible enough to let you avoid all of this, and essentially have direct acess and not worry about maintaining a sane state in your object. Wink

We can use the Struct class. The Struct's class initializer takes a list of names for members, and then dynamically creates a class with those variables and accessor methods.

code:
Character = Struct.new(:name, :race, :attack, :defense, :movement, :health)


I can then create Moglen very easily, and easily access his information.

code:
moglen_the_treacherous_lawn_gnome = Character.new("moglen", "gnome", 1, 3, 0, 10)

puts moglen_the_treacherous_lawn_gnome.name


Extending structs

Of course, structs in Ruby are just objects with lots of accessor methods. So, how can I use this to my advantage? Well, let's say all gnomes have a default set of ratings. I shouldn't, therefore, have to specify those each time I create a new Gnome. Nor, for that matter, should I have to specify that it is a Gnome.

code:
class Gnome < Character
   def initialize(name)
      super("", "Gnome", 1, 3, 0, 10)
      @name = name
   end
end


Now, I can create Moglen with:

code:
moglen_the_treacherous_lawn_gnome = Gnome.new("moglen")
Sponsor
Sponsor
Sponsor
sponsor
Cervantes




PostPosted: Mon Aug 08, 2005 7:00 am   Post subject: (No subject)

Thanks wtd! This is so elegantly simple, and so powerful.

I have one minor question, though: Why do you have this line in your Gnome class?
code:

@name = name

I know what you're trying to do, but I don't think it works. I tested this in irb and my Elf didn't keep his name. The gnomes, however, kept their names. Their class looks like this:
code:

class Gnome < Character
   def initialize(name)
      super(name, "Gnome", 1, 3, 0, 10)
   end
end


Thanks again, wtd!
wtd




PostPosted: Mon Aug 08, 2005 12:07 pm   Post subject: (No subject)

Cervantes wrote:
Thanks wtd! This is so elegantly simple, and so powerful.

I have one minor question, though: Why do you have this line in your Gnome class?
code:

@name = name

I know what you're trying to do, but I don't think it works. I tested this in irb and my Elf didn't keep his name. The gnomes, however, kept their names. Their class looks like this:
code:

class Gnome < Character
   def initialize(name)
      super(name, "Gnome", 1, 3, 0, 10)
   end
end


Thanks again, wtd!


Ok, your version works better. I don't deal much with structs, so I guess their internal organization is a bit different than I had thought.

The "@name = name" is creating an instance variable. The "@" indicates that the variable's scope extends beyond the current method, to the entire object. Thus "@name" created within initialize is available to all other methods.

However, it is not available outside of the object.
rizzix




PostPosted: Mon Aug 08, 2005 3:30 pm   Post subject: (No subject)

you said ruby automatically crerates accessor and mutator methods for an instance variable right? what are they for the variable "name".

instead of directly modifying @name, use the respective mutator.. wouldn't that work?
wtd




PostPosted: Mon Aug 08, 2005 7:08 pm   Post subject: (No subject)

rizzix wrote:
you said ruby automatically crerates accessor and mutator methods for an instance variable right? what are they for the variable "name".


For instance variables in a Struct, yes. Not for instance variables in any class. There you have to use the attr, attr_reader, attr_writer, or attr_accessor methods.

rizzix wrote:
instead of directly modifying @name, use the respective mutator.. wouldn't that work?


Yep.

code:
self.name = name
rizzix




PostPosted: Mon Aug 08, 2005 7:27 pm   Post subject: (No subject)

yep...

wait... lvalue mutators?
wtd




PostPosted: Mon Aug 08, 2005 8:37 pm   Post subject: (No subject)

code:
irb(main):001:0> class Foo
irb(main):002:1>    attr_accessor :bar, :baz
irb(main):003:1>
irb(main):004:1*    def initialize(bar, baz)
irb(main):005:2>       @bar, @baz = bar, baz
irb(main):006:2>    end
irb(main):007:1> end
=> nil
irb(main):008:0> f = Foo.new(42, 37)
=> #<Foo:0x2dbb288 @bar=42, @baz=37>
irb(main):009:0> f.bar = 23
=> 23
irb(main):010:0> f
=> #<Foo:0x2dbb288 @bar=23, @baz=37>
irb(main):011:0>
Display posts from previous:   
   Index -> Programming, Ruby -> Ruby Tutorials
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 7 Posts ]
Jump to:   


Style:  
Search: