class List
attr_reader :car, :cdr, :size
def initialize(*args)
if args.size.zero? then
@car = nil; @cdr = nil; @size = 0
elsif args.size == 1
@car = args[0]; @cdr = List.new; @size = 1
else
@car = args[0]
@cdr = List.new *args[1 .. args.size - 1]
@size = args.size
end
end
def [](n)
raise ArgumentError unless n.class == Fixnum
unless n > @size - 1 then
if n.zero? then @car
else @cdr[n - 1] end
end
end
def []=(n,a)
raise ArgumentError unless n.class == Fixnum
unless n > @size - 1 then
if n.zero? then @car = a
else @cdr[n-1] = a end
else raise ArgumentError
end
end
def length
@size
end
def null?
@cdr.nil?
end
def member?(a)
if a.nil? then true end
unless self.null? then
if @car == a then true
else @cdr.member? a end
else false
end
end
def include?(a)
self.member? a
end
end
more than the standard "just car and cdr" crap
You can extend >>14 just like in lisp by writing functions that operate on the structure returned by the list function.
Of course the clean way to do it in ruby is defining a list class but then you hide the implementation and use names like head and tail that actually make sense for a list.