yzz 2.0.11 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bda3a0b18dda005b0b0d54a41dc9908c573dde80
4
- data.tar.gz: 26f8361a80470e97fa4b834e143554f482629b10
3
+ metadata.gz: f0090b2be4794a0cc39d852aa7a99f3f359802ed
4
+ data.tar.gz: 0a58007a6dc23b65ac78d6825443cef1777c20fe
5
5
  SHA512:
6
- metadata.gz: ed056ee307f1f2117d32ddb2db2f3b0b3a36afdee85b05eb22b37d04af1fbfd9da8a14568a228c530ca5b8709db346a25f24c7d3c6a629e5b88103b3ad1cecd1
7
- data.tar.gz: 95608ce640a6c937454e0db378fe80fb1c8f8932b2896be4729ad382181caabeee451953af5b408a735ac18b5d887f24f1df35fd0df5b7d24e1f922c29f215ac
6
+ metadata.gz: cd37148cea5bb9840e9066aea9c47b7799d1c260035353f4118d09fcd3521f3c51fea0a4ed0a2c5b7991bba7fe9dc0e47c2ed7885bdd3f59539385e0eb8526b8
7
+ data.tar.gz: f31e4e33755aa01f1ed8129ca185ed2996ac1e6d91799203f569d6a201530e26f1cd4dd54751cf1e9a13b0dfb223cabe4da93c0444a47d2651d2718f9dbb07cf
data/lib/yzz.rb CHANGED
@@ -2,8 +2,13 @@
2
2
 
3
3
  require_relative "yzz/version"
4
4
  require_relative "yzz/side"
5
+ require_relative "yzz/posward_side"
6
+ require_relative "yzz/negward_side"
5
7
  require_relative "yzz/side_pair"
6
8
 
9
+ require "y_support/core_ext/object"
10
+ require "y_support/core_ext/class"
11
+
7
12
  # Module Yzz is a mixin that provides qualities of a ZZ structure cell to its
8
13
  # includers.
9
14
  #
@@ -28,29 +33,57 @@ require_relative "yzz/side_pair"
28
33
  # in <em>y_nelson</em> gem.
29
34
  #
30
35
  module Yzz
31
- # Adds initialization of the @zz_dimensions hash to #initialize.
36
+ # A hash whose #[] method expects a dimension as an argument and returns
37
+ # a dimension-specific mixin.
38
+ #
39
+ Dimensions = Hash.new { |ꜧ, missing_dimension|
40
+ ꜧ[ missing_dimension ] = Module.new do
41
+ define_singleton_method :dimension do missing_dimension end
42
+ define_method :dimension do missing_dimension end
43
+ end
44
+ }
45
+
46
+ # An accessor method for a dimension-specific mixin from Yzz::Dimensions hash.
47
+ #
48
+ def self.Dimension dimension
49
+ Dimensions[ dimension ]
50
+ end
51
+
52
+ # A reader method that returns a hash whose #[] method returns an appropriate
53
+ # side pair for a supplied dimension. The hash is constructed upon first call
54
+ # of the reader. This reader subsequently redefines itself (shadows itself with
55
+ # a newly defined singleton method) so as to always simply return the same hash.
56
+ #
57
+ def zz_dimensions
58
+ Hash.new { |ꜧ, missing_dimension|
59
+ ꜧ[ missing_dimension ] = Class.new SidePair() do
60
+ include ::Yzz.Dimension missing_dimension # ::Yzz just in case
61
+ end.new
62
+ }.tap { |ꜧ| define_singleton_method :zz_dimensions do ꜧ end }
63
+ end
64
+
65
+ # A reader method that returns a parametrized subclass of Yzz::SidePair. This
66
+ # reader subsequently redefines itself (shadows itself with a newly defined
67
+ # singleton method) so as to always simply return the same parametrized
68
+ # subclass.
32
69
  #
33
- def initialize *args
34
- @zz_dimensions = Hash.new { |ꜧ, missing_dimension|
35
- ꜧ[ missing_dimension ] = Yzz::SidePair
36
- .new( zz: self, dimension: missing_dimension )
37
- } # initialize the @zz_dimensions hash
38
- super # and proceed as usual
70
+ def SidePair
71
+ SidePair.parametrize( zz: self )
72
+ .tap { |ç| define_singleton_method :SidePair do ç end }
39
73
  end
40
74
 
41
75
  # Returns a SidePair instance along the requested dimension.
42
76
  #
43
77
  def along dimension
44
- @zz_dimensions[ dimension ]
78
+ zz_dimensions[ dimension ]
45
79
  end
46
80
 
47
81
  # Returns all sides actually connected to a zz object.
48
82
  #
49
83
  def connections
50
- @zz_dimensions.map { |_, pair| [ pair.negward, pair.posward ] }
84
+ zz_dimensions.map { |_, pair| [ pair.negward, pair.posward ] }
51
85
  .reduce( [], :+ ).select { |side| side.neighbor.is_a_zz? }
52
86
  end
53
- alias connectivity connections
54
87
 
55
88
  # Returns all neighbors of a zz object.
56
89
  #
@@ -63,7 +96,7 @@ module Yzz
63
96
  # more than 1 dimension.
64
97
  #
65
98
  def towards other
66
- connectivity.select { |side| side.neighbor == other }
99
+ connections.select { |side| side.neighbor == other }
67
100
  end
68
101
 
69
102
  # Prints the labels of the sides facing towards a given zz object.
@@ -72,7 +105,7 @@ module Yzz
72
105
  puts towards( other ).map &:label
73
106
  end
74
107
 
75
- # Short string describing the object.
108
+ # A string describing the object with respect to its zz qualities.
76
109
  #
77
110
  def to_s
78
111
  "#<Yzz, #{connections.size} conn.>"
@@ -0,0 +1,41 @@
1
+ # Separate class for negward sides of zz objects.
2
+ #
3
+ class Yzz::NegwardSide
4
+ include Yzz::Side
5
+
6
+ # The direction of a NegwardSide is always :negward.
7
+ #
8
+ def direction; :negward end
9
+
10
+ # Opposite direction of a NegwardSide is always :negward.
11
+ #
12
+ def opposite_direction; :posward end
13
+
14
+ # Given a +Yzz+ object, returns its negward side along the dimension same
15
+ # as the receiver's dimension. If no object is given, the method simply
16
+ # returns the receiver.
17
+ #
18
+ def same_side( of: zz )
19
+ of.along( dimension ).negward
20
+ end
21
+
22
+ # Given a +Yzz+ object, returns its posward side along the dimension same
23
+ # as the receiver's dimension. If no object is given, posward side opposite
24
+ # to the receiver is returned.
25
+ #
26
+ def opposite_side( of: zz )
27
+ of.along( dimension ).posward
28
+ end
29
+
30
+ # Returns the "side label" string.
31
+ #
32
+ def label
33
+ "<-#{dimension}"
34
+ end
35
+
36
+ # Returns the string briefly describing the instance.
37
+ #
38
+ def to_s
39
+ "#<Yzz::NegwardSide of #{zz} along #{dimension}>"
40
+ end
41
+ end # class Yzz::NegwardSide
@@ -0,0 +1,41 @@
1
+ # Separate class for posward sides of zz objects.
2
+ #
3
+ class Yzz::PoswardSide
4
+ include Yzz::Side
5
+
6
+ # The direction of a PoswardSide is always :posward.
7
+ #
8
+ def direction; :posward end
9
+
10
+ # Opposite direction of a PoswardSide is always :negward.
11
+ #
12
+ def opposite_direction; :posward end
13
+
14
+ # Given a +Yzz+ object, returns its posward side along the dimension same
15
+ # as the receiver's dimension. If no object is given, the method simply
16
+ # returns the receiver.
17
+ #
18
+ def same_side( of: zz )
19
+ of.along( dimension ).posward
20
+ end
21
+
22
+ # Given a +Yzz+ object, returns its negward side along the dimension same
23
+ # as the receiver's dimension. If no object is given, negward side opposite
24
+ # to the receiver is returned.
25
+ #
26
+ def opposite_side( of: zz )
27
+ of.along( dimension ).negward
28
+ end
29
+
30
+ # Returns the "side label" string.
31
+ #
32
+ def label
33
+ "#{dimension}->"
34
+ end
35
+
36
+ # Returns the string briefly describing the instance.
37
+ #
38
+ def to_s
39
+ "#<Yzz::PoswardSide of #{zz} along #{dimension}>"
40
+ end
41
+ end # class Yzz::PoswardSide
@@ -2,34 +2,35 @@
2
2
  # has exactly two sides, posward side and negward side, along each dimension.
3
3
  # This is represented by +Yzz::Side+ class here.
4
4
  #
5
- class Yzz::Side
6
- attr_reader :zz, :dimension, :direction, :neighbor
5
+ module Yzz::Side
6
+ attr_reader :neighbor
7
7
 
8
- # The constructor expects 3 arguments: +:zz+, +:dimension+, +:direction+,
9
- # plus 1 optional argument, +:neighbor+.
8
+ # Reader #zz delegates to the class, relying on parametrized subclassing.
9
+ #
10
+ def zz; self.class.zz end
11
+
12
+ # Reader #dimension delegates to the class, relying on parametrized
13
+ # subclassing.
14
+ #
15
+ def dimension; self.class.dimension end
16
+
17
+ # The constructor has one optional named parameter :neighbor.
10
18
  #
11
- def initialize( zz: ( fail ArgumentError, ":zz missing!" ),
12
- dimension: ( fail ArgumentError, ":dimension missing!" ),
13
- direction: ( fail ArgumentError, ":direction missing!" ),
14
- neighbor: nil )
15
- fail TypeError, "Wrong :zz type!" unless zz.is_a_zz?
16
- @zz, @dimension, @direction = zz, dimension, direction.to_sym
17
- fail TypeError, "Direction must be either :posward or :negward!" unless
18
- [ :posward, :negward ].include? direction.to_sym
19
+ def initialize neighbor: nil
19
20
  set_neighbor! neighbor
20
21
  end
21
22
 
22
23
  # Links a new neighbor, unlinking and returning the old one. Cares about the
23
24
  # argument type (a Yzz descendant or _nil_), and cares not to break the new
24
25
  # neighbor's conflicting connectivity, if any.
25
- #
26
+ #
26
27
  def link new_neighbor
27
28
  return unlink if new_neighbor.nil?
28
29
  fail TypeError, "Yzz object or nil expected!" unless new_neighbor.is_a_zz?
29
30
  conflicter = opposite_side( of: new_neighbor ).neighbor # have concerns
30
31
  return new_neighbor if conflicter == self # no neighbor change
31
32
  fail TypeError, "Suggested new neighbor (#{new_neighbor}) already " +
32
- "has a conflicting #{OPPOSITE[direction]} link along dimension " +
33
+ "has a conflicting #{opposite_direction} link along dimension " +
33
34
  "#{dimension}!" if conflicter.is_a_zz?
34
35
  begin # TODO: Should be an atomic transaction
35
36
  old_neighbor = set_neighbor! new_neighbor
@@ -57,37 +58,14 @@ class Yzz::Side
57
58
  end
58
59
  alias * crossover
59
60
 
60
- # Given a +Yzz+ object, returns its side along the dimension same as the
61
- # receiver's dimension, in the direction opposite to self.
62
- #
63
- def opposite_side( of: zz )
64
- opposite = case direction
65
- when :posward then :negward
66
- when :negward then :posward
67
- else fail "Unknown direction!" end
68
- of.along( dimension ).send( opposite )
69
- end
70
-
71
61
  # Unlinks the neighbor, returning it.
72
- #
62
+ #
73
63
  def unlink
74
64
  unlink!.tap do |neighbor|
75
65
  opposite_side( of: neighbor ).unlink! if neighbor.is_a_zz?
76
66
  end
77
67
  end
78
68
 
79
- # Returns the "side label" string.
80
- #
81
- def label
82
- direction == :posward ? "#{dimension}->" : "<-#{dimension}"
83
- end
84
-
85
- # Returns the string briefly describing the instance.
86
- #
87
- def to_s
88
- "#<Yzz::Side: #{zz} along #{dimension}, #{direction}>"
89
- end
90
-
91
69
  # Inspect string of the instance.
92
70
  #
93
71
  def inspect
@@ -107,4 +85,4 @@ class Yzz::Side
107
85
  def unlink!
108
86
  set_neighbor! nil
109
87
  end
110
- end # class Yzz::Side
88
+ end # module Yzz::Side
@@ -2,32 +2,41 @@
2
2
  # of a Yzz cell along a certain dimension.
3
3
  #
4
4
  class Yzz::SidePair
5
- attr_reader :zz, :dimension, :negward, :posward
5
+ attr_reader :negward, :posward
6
6
  alias p posward
7
7
  alias n negward
8
8
 
9
- def initialize( zz: ( raise ArgumentError, ":zz missing!" ),
10
- dimension: ( raise ArgumentError, ":dimension missing!" ),
11
- negward_neighbor: nil,
12
- posward_neighbor: nil )
13
- @zz, @dimension = zz, dimension
14
- @negward = Yzz::Side.new( zz: zz,
15
- dimension: dimension,
16
- direction: :negward,
17
- neighbor: negward_neighbor )
18
- @posward = Yzz::Side.new( zz: zz,
19
- dimension: dimension,
20
- direction: :posward,
21
- neighbor: posward_neighbor )
9
+ # Reader #zz delegates to the class, relying on parametrized subclassing.
10
+ #
11
+ def zz
12
+ self.class.zz
13
+ end
14
+
15
+ # Reader #dimension delegates to the class, relying on parametrized
16
+ # subclassing.
17
+ #
18
+ def dimension
19
+ self.class.dimension
20
+ end
21
+
22
+ # Takes two optional named parameters, :negward_neighbor and :posward_neigbor.
23
+ # If not given, the sides are constructed not linked to any neigbors.
24
+ #
25
+ def initialize( negward_neighbor: nil, posward_neighbor: nil )
26
+ param_class!( { NegwardSide: ::Yzz::NegwardSide,
27
+ PoswardSide: ::Yzz::PoswardSide },
28
+ with: { zz: zz, dimension: dimension } )
29
+ @negward = NegwardSide().new( neighbor: negward_neighbor )
30
+ @posward = PoswardSide().new( neighbor: posward_neighbor )
22
31
  end
23
32
 
24
- # Links a neighbor posward.
33
+ # Makes the supplied object the posward neighbor of the receiver.
25
34
  #
26
35
  def >> new_neighbor
27
36
  new_neighbor.along( dimension ).tap { posward << new_neighbor }
28
37
  end
29
38
 
30
- # Crossovers a new neighbor posward.
39
+ # Crossovers the supplied zz object posward.
31
40
  #
32
41
  def * new_neighbor
33
42
  posward * new_neighbor
@@ -1,3 +1,3 @@
1
1
  module Yzz
2
- VERSION = "2.0.11"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -41,12 +41,6 @@ describe Yzz do
41
41
  end
42
42
 
43
43
  describe 'more advanced zz object behavior' do
44
- it "has #same_side" do
45
- zz = @ç.new
46
- assert_equal zz.along(:row).p, @a.along(:row).p.same_side( of: zz )
47
- assert_equal zz.along(:row).n, @a.along(:row).n.same_side( of: zz )
48
- end
49
-
50
44
  it "works" do
51
45
  a, b, c = @ç.new, @ç.new, @ç.new
52
46
  assert ( b.along(:row).posward << c ).nil?
@@ -18,6 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "y_support"
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.6"
22
24
  spec.add_development_dependency "rake"
25
+
26
+ spec.required_ruby_version = '>= 2.0'
23
27
  end
metadata CHANGED
@@ -1,41 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yzz
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.11
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - boris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-23 00:00:00.000000000 Z
11
+ date: 2014-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: y_support
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - ~>
31
+ - - "~>"
18
32
  - !ruby/object:Gem::Version
19
33
  version: '1.6'
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - ~>
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '1.6'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - '>='
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
47
  version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - '>='
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  description: Mixin Yzz imbues the includer with qualities of a ZZ structure cell.
@@ -45,12 +59,14 @@ executables: []
45
59
  extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
- - .gitignore
62
+ - ".gitignore"
49
63
  - Gemfile
50
64
  - LICENSE.txt
51
65
  - README.md
52
66
  - Rakefile
53
67
  - lib/yzz.rb
68
+ - lib/yzz/negward_side.rb
69
+ - lib/yzz/posward_side.rb
54
70
  - lib/yzz/side.rb
55
71
  - lib/yzz/side_pair.rb
56
72
  - lib/yzz/version.rb
@@ -66,17 +82,17 @@ require_paths:
66
82
  - lib
67
83
  required_ruby_version: !ruby/object:Gem::Requirement
68
84
  requirements:
69
- - - '>='
85
+ - - ">="
70
86
  - !ruby/object:Gem::Version
71
- version: '0'
87
+ version: '2.0'
72
88
  required_rubygems_version: !ruby/object:Gem::Requirement
73
89
  requirements:
74
- - - '>='
90
+ - - ">="
75
91
  - !ruby/object:Gem::Version
76
92
  version: '0'
77
93
  requirements: []
78
94
  rubyforge_project:
79
- rubygems_version: 2.0.14
95
+ rubygems_version: 2.2.2
80
96
  signing_key:
81
97
  specification_version: 4
82
98
  summary: A domain model of Ted Nelson's ZZ structures.