Class: Relisp::Cons

Inherits:
Proxy show all
Defined in:
lib/relisp/type_conversion/programming_types.rb

Overview

A proxy to an Emacs cons. If the cons is actually a list, the to_list method will convert it a subclass of Array so that all of the ruby Array stuff is available.

Instance Attribute Summary

Attributes inherited from Proxy

#elisp_variable, #slave

Instance Method Summary collapse

Methods inherited from Proxy

elisp_alias, from_elisp, #makunbound, #to_elisp

Constructor Details

#initialize(*args) ⇒ Cons

args can be any of these forms:

  • (symbol, slave = Relisp.default_slave)

  • (_car, cdr, slave = Relisp.default_slave)

When a symbol is given it is considered to be the name of a pre-existing cons in the slave process. Otherwise a new cons is created with the given car and _cdr (cons).



155
156
157
158
159
# File 'lib/relisp/type_conversion/programming_types.rb', line 155

def initialize(*args)
  super do |car, cdr|
    @slave.elisp_exec( "(setq #{@elisp_variable} (cons #{car.to_elisp} #{cdr.to_elisp}))")
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Relisp::Proxy

Instance Method Details

#car=(newcar) ⇒ Object

Set the car of Cons to be newcar (setcar).



163
164
165
# File 'lib/relisp/type_conversion/programming_types.rb', line 163

def car=(newcar)
  @slave.setcar(@elisp_variable.value, newcar)
end

#cdr=(newcdr) ⇒ Object

Set the cdr of Cons to be newcdr. (setcdr).



169
170
171
# File 'lib/relisp/type_conversion/programming_types.rb', line 169

def cdr=(newcdr)
  @slave.setcdr(@elisp_variable.value, newcdr)
end

#list?Boolean

This function will NOT return true whenever the elisp function listp is true. The elisp function is true whenever the object is a cons cell, but this method is true only when the cons can be unambiguously translated to an array; this condition is satisfied when the object in question could have been written using the elisp function list.

Returns:

  • (Boolean)


193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/relisp/type_conversion/programming_types.rb', line 193

def list?
  # current_cdr = cdr
  # while current_cdr.kind_of?(Cons)
  #   current_cdr = current_cdr.cdr
  # end
  # return ! current_cdr.nil?

  current_cdr_var = @slave.new_elisp_variable
  @slave.elisp_exec "(setq #{current_cdr_var} (cdr #{to_elisp}))"
  while @slave.elisp_eval "(consp #{current_cdr_var})"
    @slave.elisp_exec "(setq #{current_cdr_var} (cdr #{current_cdr_var}))"
  end
  cdr = @slave.elisp_eval "#{current_cdr_var}"
  @slave.elisp_exec "(makunbound '#{current_cdr_var})"

  return ! cdr
end

#to_listObject Also known as: to_a

Translate the cons cell into a Relisp::List, a subclass of Array. See list? for when this can be done.



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/relisp/type_conversion/programming_types.rb', line 214

def to_list
  list_array = []

  # list_array << @slave.elisp_eval("(car #{to_elisp})")
  # current_cdr = @slave.elisp_eval("(cdr #{to_elisp})")
  # while current_cdr.kind_of?(Cons)
  #   list_array << @slave.elisp_eval("(car #{current_cdr.to_elisp})")
  #   current_cdr = @slave.elisp_eval("(cdr #{current_cdr.to_elisp})")
  # end

  # if current_cdr.nil?
  #   return Relisp::List.new(list_array)
  # else
  #   return false
  # end

  current_cdr_var = @slave.new_elisp_variable

  list_array << @slave.elisp_eval("(car #{to_elisp})")
  @slave.elisp_exec "(setq #{current_cdr_var} (cdr #{to_elisp}))"
  while @slave.elisp_eval "(consp #{current_cdr_var})"
    list_array << @slave.elisp_eval("(car #{current_cdr_var})")
    @slave.elisp_exec "(setq #{current_cdr_var} (cdr #{current_cdr_var}))"
  end

  cdr = @slave.elisp_eval "#{current_cdr_var}"

  @slave.elisp_exec "(makunbound '#{current_cdr_var})"

  if cdr
    raise "Not a list: #{cdr}"
  end

  return Relisp::List.new(list_array)
end