Class: Cons

Inherits:
Object
  • Object
show all
Defined in:
lib/cons.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(car = nil, cdr = nil) ⇒ Cons

Returns a new instance of Cons.



62
63
64
# File 'lib/cons.rb', line 62

def initialize car=nil, cdr=nil
  @car, @cdr = car, cdr
end

Instance Attribute Details

#carObject Also known as: first

Returns the value of attribute car.



60
61
62
# File 'lib/cons.rb', line 60

def car
  @car
end

#cdrObject Also known as: rest

Returns the value of attribute cdr.



60
61
62
# File 'lib/cons.rb', line 60

def cdr
  @cdr
end

Class Method Details

.[](car = nil, cdr = nil) ⇒ Object



366
367
368
# File 'lib/cons.rb', line 366

def [] car=nil, cdr=nil
  new car, cdr
end

.from_array(array) ⇒ Object



354
355
356
357
358
359
360
361
362
363
364
# File 'lib/cons.rb', line 354

def from_array array
  car, *cdr = array
  result = current = Cons.new
  while car and not car.nil?
    current.car = car
    current.cdr = Cons.new if cdr and not cdr.empty?
    current = current.cdr
    car, *cdr = cdr
  end
  result
end

Instance Method Details

#==(rhs) ⇒ Object



66
67
68
# File 'lib/cons.rb', line 66

def ==(rhs)
  rhs.kind_of? Cons and car == rhs.car and cdr == rhs.cdr
end

#[](n) ⇒ Object



113
114
115
# File 'lib/cons.rb', line 113

def [] n
  nth n
end

#[]=(n, value) ⇒ Object



133
134
135
# File 'lib/cons.rb', line 133

def []= n, value
  nth_eq n, value
end

#append(list, *rest) ⇒ Object

The append method returns a new list that is the concatenation of the copies. lists are left unchanged; the list structure of each of lists except the last is copied. The last argument is not copied; it becomes the cdr of the final dotted pair of the concatenation of the preceding lists, or is returned directly if there are no preceding non-empty lists.

Cf. <clhs.lisp.se/Body/f_append.htm>



288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/cons.rb', line 288

def append list, *rest
  result = self.copy_tree
  if rest.empty? or rest.nil?
    if list.kind_of? Cons
      result.the_last.cdr = list.copy_tree
    else # list is not a list
      result.the_last.cdr = list
    end
    return result
  else
    result.the_last.cdr = list.copy_tree
    return result.append *rest
  end
end

#copy_listObject Also known as: list_copy

Returns a copy of list. If list is a dotted list, the resulting list will also be a dotted list.

Cf. <clhs.lisp.se/Body/f_cp_lis.htm>



220
221
222
223
224
225
226
227
# File 'lib/cons.rb', line 220

def copy_list
  new_cdr = if cdr.kind_of? Cons
              cdr.copy_list
            else
              cdr
            end
  Cons[@car,new_cdr]
end

#copy_treeObject Also known as: tree_copy

Creates a copy of a tree of conses.

If tree is not a cons, it is returned; otherwise, the result is a new cons of the results of calling copy-tree on the car and cdr of tree. In other words, all conses in the tree represented by tree are copied recursively, stopping only when non-conses are encountered.

copy-tree does not preserve circularities and the sharing of substructure.

Cf. <clhs.lisp.se/Body/f_cp_tre.htm>



241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/cons.rb', line 241

def copy_tree
  new_car = if car.kind_of? Cons
              car.copy_tree
            else
              car
            end
  new_cdr = if cdr.kind_of? Cons
              cdr.copy_tree
            else
              cdr
            end
  Cons[new_car,new_cdr]
end

#end?Boolean Also known as: endp

Returns:

  • (Boolean)


118
119
120
# File 'lib/cons.rb', line 118

def end?
  @car.nil? and @cdr.nil?
end

#first_eq(value) ⇒ Object



141
142
143
# File 'lib/cons.rb', line 141

def first_eq value
  @car = value
end

#last(n = nil) ⇒ Object

last returns the last n conses (not the last n elements) of list). If n is zero, the atom that terminates list is returned. If n is greater than or equal to the number of cons cells in list, the result is list.

Cf. <clhs.lisp.se/Body/f_last.htm>



271
272
273
274
275
276
277
278
279
# File 'lib/cons.rb', line 271

def last n=nil
  if n.nil? or n == 1
    return the_last
  elsif n <= 0
    return Cons[]
  else
    return nthcdr length-n
  end
end

#lengthObject Also known as: list_length



70
71
72
73
74
75
76
77
78
# File 'lib/cons.rb', line 70

def length
  result = 0
  current = self
  while current and current.car and not current.car.nil?
    result += 1
    current = current.cdr
  end
  result
end

#nth(n) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/cons.rb', line 104

def nth n
  i = nthcdr n
  if i.nil?
    nil
  else
    nthcdr(n).car
  end
end

#nth_eq(n, value) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/cons.rb', line 124

def nth_eq(n, value)
  i = nthcdr(n)
  if i.nil?
    raise RuntimeError
  else
    nthcdr(n).car= value
  end
end

#nthcdr(n) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/cons.rb', line 90

def nthcdr n
  if not n.kind_of? Integer
    raise ArgumentError, "n for nthcdr must be an integer"
  elsif n <= 0
    self
  elsif n > 0
    if cdr.nil?
      nil
    else
      cdr.nthcdr n-1
    end
  end
end

#popObject

The pop method reads the value of place, remembers the car of the list which was retrieved, writes the cdr of the list back into the place, and finally yields the car of the originally retrieved list.

Cf. <clhs.lisp.se/Body/m_pop.htm>



308
309
310
311
312
313
314
# File 'lib/cons.rb', line 308

def pop
  result = @car
  n = @cdr
  @car = n.car
  @cdr = n.cdr
  return result
end

#push(value) ⇒ Object

push prepends item to the list that is stored in place, stores the resulting list in place, and returns the list.

Cf. <clhs.lisp.se/Body/m_push.htm>



320
321
322
323
324
# File 'lib/cons.rb', line 320

def push value
  @cdr = Cons[@car,@cdr]
  @car = value
  return self
end

#the_lastObject

The the_last method returns the last cdr that is a cons.



258
259
260
261
262
263
264
# File 'lib/cons.rb', line 258

def the_last
  if @cdr.kind_of? Cons
    return @cdr.last
  else
    return self
  end
end

#to_aObject



206
207
208
209
210
211
212
213
214
# File 'lib/cons.rb', line 206

def to_a
  if not car or car.nil?
    []
  elsif not cdr or cdr.nil?
    [car]
  else
    [car] + cdr.to_a
  end
end