The constructor of every class in ruby is called initialize. You can define a constructor by simply defining a function with that name, and any arguments you pass to MyClass.new will be passed to initialize. You do not have to specify a constructor if you don't want to; ruby will create one with no parameters that does nothing if you like. In this case, every field will initially be nil, if you try to access it.
Object fields in ruby are denoted by the enforced convention of the @ sign. For example, saying
class DListNode
def initialize
@item = 5
end
end
will, on the creation of a new DListNode object, set the object's size field to 5. You can define methods just as you defined the constructor, although obviously methods can have any name you like. Except they can't start with a capital letter. Or @.
Ruby has a very cool convention for writing functions to access object fields. There are three built in functions called attribute_accessor, attribute_reader and attribute_writer, which each take in a variable number of symbols and set permissions accordingly. For example, if you wanted to have the size of a DList (doubly linked list data structure) be accessible to any program that wanted to read it, but keep programs from changing it, you would say attribute_reader :size, conventionally before you define initialize. This means that some other program would be able to say my_dlist.size and it would return the correct value, but it would not be able to say my_dlist.size = 6.
If you wanted to make the size field totally public, you could say attribute_accessor :size instead, which would allow other programs to change my_dlist.size. If for some reason (I can't think of any at the moment) you only wanted other programs to have write access, you could say attribute_writer :size.
Note that this means, if you specified attribute_reader for a field, you do not have to refer to it with the @ prefix later on. However, if you did not specify read access, you still need to say @size, instead of just size. This is because, I believe, ruby looks at the object fields first when looking for a value of a name inside a class.
Here's a full (though not fully well encapsulated) implementation of a doubly linked list in ruby for you to look over.
class DListNode
attr_accessor :item, :nextone, :prevone
def initialize(item=nil, nextone=nil, prevone=nil)
@item = item
@next = nextone
@prevone = prevone
end
def to_s
if nextone.item == nil
return item.to_s unless item == nil
return 'nil'
end
return item.to_s + ', ' + nextone.to_s unless item == nil
return 'nil, ' + nextone.to_s
end
end
class DList
attr_reader :size
def initialize
@size = 0
@head = DListNode.new
@head.nextone = @head
@head.prevone = @head
end
def add item
node = DListNode.new item
node.prevone = @head.prevone
node.nextone = @head
node.prevone.nextone = node
node.nextone.prevone = node
@size += 1
end
def to_s
'['+@head.nextone.to_s+']'
end
end
So that's how to define classes in ruby.
No comments:
Post a Comment