yzz 2.0.11 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/yzz.rb +45 -12
- data/lib/yzz/negward_side.rb +41 -0
- data/lib/yzz/posward_side.rb +41 -0
- data/lib/yzz/side.rb +17 -39
- data/lib/yzz/side_pair.rb +25 -16
- data/lib/yzz/version.rb +1 -1
- data/test/yzz_test.rb +0 -6
- data/yzz.gemspec +4 -0
- metadata +27 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0090b2be4794a0cc39d852aa7a99f3f359802ed
|
4
|
+
data.tar.gz: 0a58007a6dc23b65ac78d6825443cef1777c20fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
#
|
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
|
34
|
-
|
35
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
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
|
data/lib/yzz/side.rb
CHANGED
@@ -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
|
-
|
6
|
-
attr_reader :
|
5
|
+
module Yzz::Side
|
6
|
+
attr_reader :neighbor
|
7
7
|
|
8
|
-
#
|
9
|
-
#
|
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
|
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 #{
|
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 #
|
88
|
+
end # module Yzz::Side
|
data/lib/yzz/side_pair.rb
CHANGED
@@ -2,32 +2,41 @@
|
|
2
2
|
# of a Yzz cell along a certain dimension.
|
3
3
|
#
|
4
4
|
class Yzz::SidePair
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :negward, :posward
|
6
6
|
alias p posward
|
7
7
|
alias n negward
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
#
|
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
|
39
|
+
# Crossovers the supplied zz object posward.
|
31
40
|
#
|
32
41
|
def * new_neighbor
|
33
42
|
posward * new_neighbor
|
data/lib/yzz/version.rb
CHANGED
data/test/yzz_test.rb
CHANGED
@@ -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?
|
data/yzz.gemspec
CHANGED
@@ -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
|
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-
|
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.
|
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.
|