[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Ruby-ize me (or at least my code

Seth Eliot

10/22/2006 10:51:00 PM

Hi all,

I am new to Ruby but find it interesting. To teach myself the language
I wrote a simple linked list implementation. It works just fine, but I
suspect that my "Java is showing" and that the same logic can be written
in a much more Ruby-ish fashion.

So I'd appreciate it if you can show me the Ruby way of implementing the
following functionality.

(The one thing I know is that I am not really taking advantage of OOP by
making my methods in LinkedListSe.rb just static utility methodsâ?¦ that's
fine for now)
(also "next_1" is just my way of not colliding with the reserved keyword
"next")

File: ElemLL.rb

class ElemLL

attr_accessor :data, :next_1

@data
@next_1
End

File: LinkedListSe.rb

require 'ElemLL'

# Adds element to end of linked list
def addData(data, head=nil)
insertData(data, head)
end

# Inserts Element at requested index in linked list.
# Shifts the element currently at that position (if any) and any
subsequent
# elements to the right (adds one to their indices)
def insertData(data, head, index=nil)

# special case if list currently empty (not initialized)
return newList(data) unless head

# Weakly typed languages have their downsides? :-)
return unless head.class == ElemLL

# Initial values for first element
i = 1
prev = nil
curr = head
next_1 = curr.next_1

# Iterate through elements until we reach insertion point (or end of
list)
while (curr && (!index || i<index))
prev=curr
curr = next_1;
next_1 = curr.next_1 if curr;
i=i.next
end

# when new element is inserted, the current curr will actually be
next
next_1 = curr

# Create the new element at curr
curr = ElemLL.new
curr.data = data
curr.next_1=next_1

# Set the pointer *to* the new element
if (prev)
prev.next_1 = curr
else
head=curr
end

return head
end

def traverse(head)
puts "\nLinked List contents:"

curr = head
while(curr)
puts " #{curr.data}"
curr = curr.next_1
end
end

def newList(data)
head = ElemLL.new
head.data = data
return head
end

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

7 Answers

Seth Eliot

10/22/2006 11:10:00 PM

0

Just wanted to clarify: I know that there are better ways to do a
Linked List in Ruby... namely the Array object seems to have everything
you would need. So the code here is just an exercise, and I'm curious
how the same code can be made more ruby-ish

Also.....

Seth E. wrote:
> # Weakly typed languages have their downsides? :-)
> return unless head.class == ElemLL

doh! I meant *dynamically* typed... I know Ruby is Strongly typed. And
I also *do* understand the advantages of a dynamically typed language
:-)


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

David Vallner

10/22/2006 11:11:00 PM

0

Seth Eliot wrote:
> Hi all,
>
> I am new to Ruby but find it interesting. To teach myself the language
> I wrote a simple linked list implementation. It works just fine, but I
> suspect that my "Java is showing" and that the same logic can be written
> in a much more Ruby-ish fashion.
>
> So I'd appreciate it if you can show me the Ruby way of implementing the
> following functionality.
>
> (The one thing I know is that I am not really taking advantage of OOP by
> making my methods in LinkedListSe.rb just static utility methods… that's
> fine for now)
> (also "next_1" is just my way of not colliding with the reserved keyword
> "next")
>
> File: ElemLL.rb
>
> class ElemLL
>
> attr_accessor :data, :next_1
>

The following two lines don't in fact do anything and can be safely deleted.

> @data
> @next_1
> End
>

The following should be methods of ElemLL. (There's not *much* Java
showing, is there?)

> File: LinkedListSe.rb
>
> require 'ElemLL'
>
> # Adds element to end of linked list
> def addData(data, head=nil)
> insertData(data, head)
> end
>
> # Inserts Element at requested index in linked list.
> # Shifts the element currently at that position (if any) and any
> subsequent
> # elements to the right (adds one to their indices)
> def insertData(data, head, index=nil)
>
> # special case if list currently empty (not initialized)
> return newList(data) unless head
>

If you're doing type-checking, raise an exception. This is a potential
Mysterious Bug. ("Nothing seem to be broke, it just doesn't work!")

> # Weakly typed languages have their downsides? :-)
> return unless head.class == ElemLL
>
> # Initial values for first element
> i = 1
> prev = nil
> curr = head
> next_1 = curr.next_1
>
> # Iterate through elements until we reach insertion point (or end of
> list)
> while (curr && (!index || i<index))
> prev=curr
> curr = next_1;
> next_1 = curr.next_1 if curr;
> i=i.next
> end
>
> # when new element is inserted, the current curr will actually be
> next
> next_1 = curr
>
> # Create the new element at curr
> curr = ElemLL.new
> curr.data = data
> curr.next_1=next_1
>
> # Set the pointer *to* the new element
> if (prev)
> prev.next_1 = curr
> else
> head=curr
> end
>
> return head
> end
>

The following should be an implementation of #each:

> def traverse(head)
Axe following line.
> puts "\nLinked List contents:"
>
> curr = head
> while(curr)
Replace with "yield curr.data". For greater pleasure, have ElemLL
"include Enumerable".
> puts " #{curr.data}"
> curr = curr.next_1
> end
> end
>

The Ruby equivalent of a constructor is the "special" (i.e. not really)
method initialize.

> def newList(data)
> head = ElemLL.new
> head.data = data
> return head
> end
>

Also, I personally prefer(red) opaque linked lists (in the school
assignments where I actually implemented those.) - ones where you don't
rely on having to supply the head node of a list to functions
manipulating it, but a structure encapsulating the list. Same here, I'd
avoid leaking the internal structure of the list.

David Vallner


David Vallner

10/22/2006 11:14:00 PM

0

Seth E. wrote:
> Just wanted to clarify: I know that there are better ways to do a
> Linked List in Ruby... namely the Array object seems to have everything
> you would need.

The Array object isn't a linked list, it's an array-backed list. (The
damage freshman courses cause by making students believe linked lists
are in any way amazing. In fact, in any scenario where there's a
reasonable upper bound on the number of items in the list, an
array-backed implementation will implement a linked-list implementation
in terms of both speed and memory efficiency.)

David Vallner

Eero Saynatkari

10/23/2006

0

On 2006.10.23 07:51, Seth Eliot wrote:
> Hi all,
>
> I am new to Ruby but find it interesting. To teach myself the language
> I wrote a simple linked list implementation. It works just fine, but I
> suspect that my "Java is showing" and that the same logic can be written
> in a much more Ruby-ish fashion.

It is mostly an imperative style that is showing for some odd reason :)
Instead of critiquing, I will give you an alternative implementation to
munch upon.

> So I'd appreciate it if you can show me the Ruby way of implementing the
> following functionality.
>
> (The one thing I know is that I am not really taking advantage of OOP by
> making my methods in LinkedListSe.rb just static utility methods??? that's
> fine for now)
> (also "next_1" is just my way of not colliding with the reserved keyword
> "next")

# I have not actually run this code, just typing out at work
class Node
include Enumerable

attr_accessor 'data', 'succ'

# New node with the given data
def new(data, succ = nil)
@data, @succ = data.first, succ
end

# Chainable append from arbitrary data
def <<(data)
@succ = Node.new data
@succ
end

# Insert a node at a given position
def insert_at(pos, data)
return Node.new(data, self) if pos == 0

@succ.insert_at((pos - 1), data)
self
end

# Traversal
def each(&block)
yield @data
@succ.each &block
end

# Stringimafy
def to_s()
map {|data| data.to_s}.join ' -> '
end
end

list = Node.new('foo') << 'bar' << 'baz' << 'quux'

David Vallner

10/23/2006 12:27:00 AM

0

Eero Saynatkari wrote:
> # Stringimafy

*facedesk*

Do I see a new rubyism being born?

David Vallner

Seth Eliot

10/23/2006 12:42:00 AM

0

Thanks Eero. That is quite an eye-opener, and was exactly what I was
looking for.

> # I have not actually run this code, just typing out at work

...which probably explains what I am about to ask you, but I thought I
would double check

Eero Saynatkari wrote:
>
> # New node with the given data
> def new(data, succ = nil)
> @data, @succ = data.first, succ
> end

This should actually be this, right?

# New node with the given data
def initialize(data, succ = nil)
@data, @succ = data, succ
end

Nonetheless, with a few tweaks your example worked fine, and was quite
educational. Thanks again!

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

Christian Neukirchen

10/23/2006 9:26:00 PM

0

David Vallner <david@vallner.net> writes:

> Seth E. wrote:
>> Just wanted to clarify: I know that there are better ways to do a
>> Linked List in Ruby... namely the Array object seems to have everything
>> you would need.
>
> The Array object isn't a linked list, it's an array-backed list. (The
> damage freshman courses cause by making students believe linked lists
> are in any way amazing. In fact, in any scenario where there's a
> reasonable upper bound on the number of items in the list, an
> array-backed implementation will implement a linked-list implementation
> in terms of both speed and memory efficiency.)

But you can't do DLX with an array! ;-)

> David Vallner
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...