module Yzz

Module Yzz is a mixin that provides qualities of a ZZ structure cell to its includers.

A ZZ structure consists of ZZ objects, which exist in multiple dimensions. ZZ objects may be connected by directed edges – connections. Connected objects are called neighbors. Each connection belongs to exactly one dimension. A ZZ object is considered as having two sides in each dimension: posward side and negward side. A connection always points away from the posward side, and towards the negward side of the neighbor. In each dimension, a ZZ object can have at most one posward and one negward neighbor. The relation is bijective: If B is the posward neighbor of A along dimension X, then A is a negward neighbor of B along X, and vice-versa. There is no limitation as to what objects can be connected. Circles are allowed. A ZZ object can even be connected to itself, forming a loop.

To this basic definition, Ted Nelson adds a bunch of additional terminology. A rank is a series of ZZ objects connected along the same dimension. A rank viewed horizontally is referred to as row. A rank viewed vertically is referred to as column. Ted Nelson's terms related not to the ZZ structure itself, but rather to the proposed user interface (such as cursor, view…) are not implemented in yzz, but rather in y_nelson gem.

Constants

Dimensions

A hash whose [] method expects a dimension as an argument and returns a dimension-specific mixin.

VERSION

Public Class Methods

Dimension(dimension) click to toggle source

An accessor method for a dimension-specific mixin from Yzz::Dimensions hash.

# File lib/yzz.rb, line 48
def self.Dimension dimension
  Dimensions[ dimension ]
end

Public Instance Methods

SidePair() click to toggle source

A reader method that returns a parametrized subclass of Yzz::SidePair. This reader subsequently redefines itself (shadows itself with a newly defined singleton method) so as to always simply return the same parametrized subclass.

# File lib/yzz.rb, line 73
def SidePair
  SidePair.parametrize( zz: self )
    .tap { |ç| define_singleton_method :SidePair do ç end }
  # TODO: How about
  #
  # SidePair.parametrize zz: self do
  #   def SidePair; self end
  # end
end
along(dimension) click to toggle source

Returns a SidePair instance along the requested dimension.

# File lib/yzz.rb, line 85
def along dimension
  zz_dimensions[ dimension ]
end
connections() click to toggle source

Returns all sides actually connected to a zz object.

# File lib/yzz.rb, line 91
def connections
  zz_dimensions.map { |_, pair| [ pair.negward, pair.posward ] }
    .reduce( [], :+ ).select { |side| side.neighbor.is_a_zz? }
end
inspect() click to toggle source

Inspect string of the object.

# File lib/yzz.rb, line 124
def inspect
  to_s
end
neighbors() click to toggle source

Returns all neighbors of a zz object.

# File lib/yzz.rb, line 98
def neighbors
  connections.map &:neighbor
end
to_s() click to toggle source

A string describing the object with respect to its zz qualities.

# File lib/yzz.rb, line 118
def to_s
  "#<Yzz, #{connections.size} conn.>"
end
towards(other) click to toggle source

Returns all sides facing another zz object supplied as argument. (Note that this can be more than 1 side: object A can be connected to B along more than 1 dimension.

# File lib/yzz.rb, line 106
def towards other
  connections.select { |side| side.neighbor == other }
end
tw(other) click to toggle source

Prints the labels of the sides facing towards a given zz object.

# File lib/yzz.rb, line 112
def tw other
  puts towards( other ).map &:label
end
zz_dimensions() click to toggle source

A reader method that returns a hash whose [] method returns an appropriate side pair for a supplied dimension. The hash is constructed upon first call of the reader. This reader subsequently redefines itself (shadows itself with a newly defined singleton method) so as to always simply return the same hash.

# File lib/yzz.rb, line 57
def zz_dimensions
  Hash.new { |, missing_dimension|
    [ missing_dimension ] = Class.new SidePair() do
      include ::Yzz.Dimension missing_dimension # ::Yzz just in case
    end.new
  }.tap { || define_singleton_method :zz_dimensions do  end }
  # TODO: This second subclassing of SidePair() in effect acts as a
  # singleton class. How about making it a true singleton class and
  # just extending the objects with the mixin?
end