Class: Campa::List

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/campa/list.rb

Overview

A minimalist implementation of a Linked List.

An instance of it represents a function ivocation in the context of a Evaler#call or a Evaler#eval call.

The importance of adding the adjective “minimalist” in this description is to give already the idea that this implementation does not come with some algorithms (deleting, for example) since for this also minimal Lisp implementation this won’t be necessary.

Constant Summary collapse

EMPTY =
new

Instance Method Summary collapse

Constructor Details

#initialize(*elements) ⇒ List

Returns a new instance of List.

Parameters:

  • elements (Array<Object>)

    elements linked on the current Campa::List



19
20
21
22
23
24
25
# File 'lib/campa/list.rb', line 19

def initialize(*elements)
  @first = nil
  @head = nil
  @tail = EMPTY

  with elements
end

Instance Method Details

#==(other) ⇒ Boolean

Stablishes equality by comparing each element in the Campa::List.

Parameters:

  • other (List)

    to be compared

Returns:

  • (Boolean)

    true if of both Campa::List have equal (#==) elements



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/campa/list.rb', line 78

def ==(other)
  return false if !other.is_a?(List)

  node = first
  other_node = other.first

  loop do
    # If both node and other_node are nil
    # we managed to walk the whole list.
    # Since there was no early return (with false)
    # this means all nodes are equal.
    return node.nil? if other_node.nil?
    return false if node != other_node

    node = node.next_node
    other_node = other_node.next_node
  end
end

#each(&block) ⇒ Object

Yields each element starting from head.



66
67
68
69
70
71
# File 'lib/campa/list.rb', line 66

def each(&block)
  return if self == EMPTY

  block.call(head)
  tail.each(&block) if tail != EMPTY
end

#headObject?

First element of the current Campa::List.

Return nil if the current list is EMPTY.

Returns:

  • (Object, nil)


46
47
48
49
50
# File 'lib/campa/list.rb', line 46

def head
  return nil if self == EMPTY

  first.value
end

#inspectObject

Uses Printer to represent the current Campa::List in a human readable form.

Examples:

List.new(1, 2, 3).inspect #=> "(1 2 3)"


102
103
104
105
# File 'lib/campa/list.rb', line 102

def inspect
  @printer ||= Printer.new
  @printer.call(self)
end

#push(element) ⇒ List

Creates a new Campa::List with the parameter passed in front of it.

Examples:

List.new(2, 3).push(1) #=> List.new(1, 2, 3)

Parameters:

  • element (Object)

    any thing to be pushed into the Campa::List

Returns:



35
36
37
38
39
# File 'lib/campa/list.rb', line 35

def push(element)
  self.class.new.tap do |l|
    l.first = Node.new(value: element, next_node: first)
  end
end

#tailList

Creates a new list with all elements of the current one BUT the head.

Examples:

List.new(1, 2, 3).tail #=> List.new(2, 3)

Returns:



59
60
61
62
63
# File 'lib/campa/list.rb', line 59

def tail
  return EMPTY if first.nil? || first.next_node.nil?

  self.class.new.tap { |l| l.first = @first.next_node }
end