ember 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +79 -0
- data/INSTALL +31 -0
- data/MANUAL +25 -0
- data/README +54 -0
- data/THEORY +151 -0
- data/USAGE +250 -0
- data/bin/ember +58 -20
- data/doc/ann.xml +93 -0
- data/doc/api/Ember.html +436 -0
- data/doc/api/Ember/Template.html +774 -0
- data/doc/api/Ember/Template/Program.html +877 -0
- data/doc/api/Ember/Template/Program/Statement.html +181 -0
- data/doc/api/_index.html +139 -0
- data/doc/api/class_list.html +36 -0
- data/doc/api/css/common.css +1 -0
- data/doc/api/css/full_list.css +50 -0
- data/doc/api/css/style.css +273 -0
- data/doc/api/file.LICENSE.html +73 -0
- data/doc/api/file_list.html +38 -0
- data/doc/api/frames.html +13 -0
- data/doc/api/index.html +72 -13
- data/doc/api/js/app.js +111 -0
- data/doc/api/js/full_list.js +117 -0
- data/doc/api/js/{jquery-1.3.2.min.js → jquery.js} +0 -0
- data/doc/api/method_list.html +179 -0
- data/doc/api/top-level-namespace.html +87 -0
- data/doc/index.html +1353 -682
- data/inochi.opts +31 -0
- data/lib/ember.rb +1 -15
- data/lib/ember/inochi.rb +103 -0
- data/lib/ember/template.rb +66 -78
- data/test/combinatorics.rb +188 -0
- data/test/ember/template_test.rb +137 -0
- data/test/runner +25 -0
- data/test/test_helper.rb +5 -0
- metadata +61 -51
- data/doc/api/apple-touch-icon.png +0 -0
- data/doc/api/classes/Ember.html +0 -61
- data/doc/api/classes/Ember/Template.html +0 -413
- data/doc/api/classes/Ember/Template/Program.html +0 -60
- data/doc/api/created.rid +0 -1
- data/doc/api/css/main.css +0 -263
- data/doc/api/css/panel.css +0 -383
- data/doc/api/css/reset.css +0 -53
- data/doc/api/favicon.ico +0 -0
- data/doc/api/files/LICENSE.html +0 -76
- data/doc/api/files/lib/ember/template_rb.html +0 -66
- data/doc/api/files/lib/ember_rb.html +0 -63
- data/doc/api/i/arrows.png +0 -0
- data/doc/api/i/results_bg.png +0 -0
- data/doc/api/i/tree_bg.png +0 -0
- data/doc/api/js/jquery-effect.js +0 -593
- data/doc/api/js/main.js +0 -22
- data/doc/api/js/searchdoc.js +0 -628
- data/doc/api/panel/index.html +0 -71
- data/doc/api/panel/search_index.js +0 -1
- data/doc/api/panel/tree.js +0 -1
- data/doc/history.erb +0 -34
- data/doc/index.erb +0 -11
- data/doc/intro.erb +0 -53
- data/doc/setup.erb +0 -78
- data/doc/usage.erb +0 -280
- data/rakefile +0 -14
- data/test/ember.rb +0 -17
- data/test/ember/template.rb +0 -141
data/inochi.opts
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
##
|
2
|
+
# Location where project documentation will be uploaded by `inochi pub:doc`.
|
3
|
+
# This value can utilize any remote/destination syntax supported by `rsync`.
|
4
|
+
#
|
5
|
+
:pub_doc_target: ~/www/lib/ember
|
6
|
+
|
7
|
+
##
|
8
|
+
# Options for the `rsync` command used to upload this project's documentation.
|
9
|
+
#
|
10
|
+
:pub_doc_options: --verbose --compress --archive --update --delete
|
11
|
+
|
12
|
+
##
|
13
|
+
# Arbitrary Ruby code that will configure this project's RubyGem before it
|
14
|
+
# is built by `inochi gem`. This code has access to a local variable named
|
15
|
+
# `gem` which holds a Gem::Specification object representing this project.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# :gem_spec_logic: |
|
20
|
+
# # show the Inochi-provided specification for this project's RubyGem
|
21
|
+
# puts gem
|
22
|
+
#
|
23
|
+
# # add files that are outside this project directory to the RubyGem
|
24
|
+
# gem.files += FileList['/some/outside/**/*.files']
|
25
|
+
#
|
26
|
+
# # omit some files in this project's directory from the RubyGem
|
27
|
+
# gem.files.exclude '{some*files,in_this,project/**/directory}'
|
28
|
+
#
|
29
|
+
# # and so on... anything is possible! use your imagination!
|
30
|
+
#
|
31
|
+
:gem_spec_logic: |
|
data/lib/ember.rb
CHANGED
@@ -1,16 +1,2 @@
|
|
1
|
-
|
2
|
-
# Copyright protects this work.
|
3
|
-
# See LICENSE file for details.
|
4
|
-
#++
|
5
|
-
|
6
|
-
require 'rubygems'
|
7
|
-
gem 'inochi', '~> 1'
|
8
|
-
require 'inochi'
|
9
|
-
|
10
|
-
Inochi.init :Ember,
|
11
|
-
:version => '0.0.1',
|
12
|
-
:release => '2009-10-03',
|
13
|
-
:website => 'http://snk.tuxfamily.org/lib/ember/',
|
14
|
-
:tagline => 'eRuby template processor'
|
15
|
-
|
1
|
+
require 'ember/inochi'
|
16
2
|
require 'ember/template'
|
data/lib/ember/inochi.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
module Ember
|
2
|
+
|
3
|
+
##
|
4
|
+
# Official name of this project.
|
5
|
+
#
|
6
|
+
PROJECT = "Ember"
|
7
|
+
|
8
|
+
##
|
9
|
+
# Short single-line description of this project.
|
10
|
+
#
|
11
|
+
TAGLINE = "eRuby template processor"
|
12
|
+
|
13
|
+
##
|
14
|
+
# Address of this project's official home page.
|
15
|
+
#
|
16
|
+
WEBSITE = "http://snk.tuxfamily.org/lib/ember/"
|
17
|
+
|
18
|
+
##
|
19
|
+
# Number of this release of this project.
|
20
|
+
#
|
21
|
+
VERSION = "0.1.0"
|
22
|
+
|
23
|
+
##
|
24
|
+
# Date of this release of this project.
|
25
|
+
#
|
26
|
+
RELDATE = "2010-04-03"
|
27
|
+
|
28
|
+
##
|
29
|
+
# Description of this release of this project.
|
30
|
+
#
|
31
|
+
def self.inspect
|
32
|
+
"#{PROJECT} #{VERSION} (#{RELDATE})"
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Location of this release of this project.
|
37
|
+
#
|
38
|
+
INSTDIR = File.expand_path('../../..', __FILE__)
|
39
|
+
|
40
|
+
##
|
41
|
+
# RubyGems required by this project during runtime.
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
#
|
45
|
+
# RUNTIME = {
|
46
|
+
# # this project needs exactly version 1.2.3 of the "an_example" gem
|
47
|
+
# "an_example" => [ "1.2.3" ],
|
48
|
+
#
|
49
|
+
# # this project needs at least version 1.2 (but not
|
50
|
+
# # version 1.2.4 or newer) of the "another_example" gem
|
51
|
+
# "another_example" => [ ">= 1.2" , "< 1.2.4" ],
|
52
|
+
#
|
53
|
+
# # this project needs any version of the "yet_another_example" gem
|
54
|
+
# "yet_another_example" => [],
|
55
|
+
# }
|
56
|
+
#
|
57
|
+
RUNTIME = {}
|
58
|
+
|
59
|
+
##
|
60
|
+
# RubyGems required by this project during development.
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
#
|
64
|
+
# DEVTIME = {
|
65
|
+
# # this project needs exactly version 1.2.3 of the "an_example" gem
|
66
|
+
# "an_example" => [ "1.2.3" ],
|
67
|
+
#
|
68
|
+
# # this project needs at least version 1.2 (but not
|
69
|
+
# # version 1.2.4 or newer) of the "another_example" gem
|
70
|
+
# "another_example" => [ ">= 1.2" , "< 1.2.4" ],
|
71
|
+
#
|
72
|
+
# # this project needs any version of the "yet_another_example" gem
|
73
|
+
# "yet_another_example" => [],
|
74
|
+
# }
|
75
|
+
#
|
76
|
+
DEVTIME = {
|
77
|
+
"inochi" => [ "~> 2" ], # for managing this project
|
78
|
+
"dfect" => [ "~> 2" ], # for unit testing
|
79
|
+
}
|
80
|
+
|
81
|
+
##
|
82
|
+
# Loads the correct version (as defined by the {RUNTIME} or {DEVTIME}
|
83
|
+
# constant in this module) of the given gem or the gem that contains
|
84
|
+
# the given library.
|
85
|
+
#
|
86
|
+
def self.require gem_name_or_library
|
87
|
+
# prepare the correct version of the gem for loading
|
88
|
+
if respond_to? :gem
|
89
|
+
gem_name = gem_name_or_library.to_s.sub(%r{/.*$}, '')
|
90
|
+
if gem_version = RUNTIME[gem_name] || DEVTIME[gem_name]
|
91
|
+
begin
|
92
|
+
gem gem_name, *gem_version
|
93
|
+
rescue LoadError => error
|
94
|
+
warn "#{self.inspect}: #{error}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# do the loading
|
100
|
+
super
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
data/lib/ember/template.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright protects this work.
|
3
|
-
# See LICENSE file for details.
|
4
|
-
#++
|
5
|
-
|
6
1
|
require 'pathname'
|
7
2
|
|
8
3
|
module Ember
|
@@ -13,53 +8,44 @@ module Ember
|
|
13
8
|
#
|
14
9
|
# This processor transforms the given input
|
15
10
|
# into an executable Ruby program (provided
|
16
|
-
# by the #program
|
17
|
-
# executed by the #render
|
11
|
+
# by the {#program} method) which is then
|
12
|
+
# executed by the {#render} method on demand.
|
18
13
|
#
|
19
14
|
# eRuby directives that contribute to the output of
|
20
15
|
# the given template are called "vocal" directives.
|
21
16
|
# Those that do not are called "silent" directives.
|
22
17
|
#
|
23
|
-
#
|
18
|
+
# @option options [String] :result_variable ("_erbout")
|
24
19
|
#
|
25
|
-
# [:result_variable]
|
26
20
|
# Name of the variable which stores the result of
|
27
21
|
# template evaluation during template evaluation.
|
28
22
|
#
|
29
|
-
#
|
23
|
+
# @option options [Boolean] :continue_result (false)
|
30
24
|
#
|
31
|
-
# [:continue_result]
|
32
25
|
# Append to the result variable if it already exists?
|
33
26
|
#
|
34
|
-
#
|
27
|
+
# @option options [String] :source_file ("SOURCE")
|
35
28
|
#
|
36
|
-
# [:source_file]
|
37
29
|
# Name of the file which contains the given input. This
|
38
30
|
# is shown in stack traces when reporting error messages.
|
39
31
|
#
|
40
|
-
#
|
32
|
+
# @option options [Integer] :source_line (1)
|
41
33
|
#
|
42
|
-
# [:source_line]
|
43
34
|
# Line number at which the given input exists in the :source_file.
|
44
35
|
# This is shown in stack traces when reporting error messages.
|
45
36
|
#
|
46
|
-
#
|
37
|
+
# @option options [Boolean] :shorthand (false)
|
47
38
|
#
|
48
|
-
# [:shorthand]
|
49
39
|
# Treat lines beginning with "%" as eRuby directives?
|
50
40
|
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
# [:infer_end]
|
54
|
-
# Add missing <% end %> statements based on indentation?
|
41
|
+
# @option options [Boolean] :infer_end (false)
|
55
42
|
#
|
56
|
-
#
|
43
|
+
# Add missing +<% end %>+ statements based on indentation?
|
57
44
|
#
|
58
|
-
# [:unindent
|
59
|
-
# Unindent the content of eRuby blocks (everything
|
60
|
-
# between <% do %> ... <% end %>) hierarchically?
|
45
|
+
# @option options [Boolean] :unindent (false)
|
61
46
|
#
|
62
|
-
#
|
47
|
+
# Unindent the content of eRuby blocks---that is everything
|
48
|
+
# between the +<% do %>+ and +<% end %>+ tags---hierarchically?
|
63
49
|
#
|
64
50
|
def initialize input, options = {}
|
65
51
|
@options = options
|
@@ -79,7 +65,7 @@ module Ember
|
|
79
65
|
|
80
66
|
##
|
81
67
|
# Returns the result of executing the Ruby program for this template
|
82
|
-
# (provided by the #program
|
68
|
+
# (provided by the {#program} method) inside the given context binding.
|
83
69
|
#
|
84
70
|
def render context = TOPLEVEL_BINDING, parent_context_id = nil
|
85
71
|
context ||= @@contexts[parent_context_id] # inherit parent context
|
@@ -141,72 +127,71 @@ module Ember
|
|
141
127
|
OPERATION_EVAL_TEMPLATE_STRING = '~'
|
142
128
|
OPERATION_INSERT_PLAIN_FILE = '<'
|
143
129
|
|
144
|
-
|
130
|
+
OPERATIONS = [
|
131
|
+
OPERATION_COMMENT_LINE,
|
132
|
+
OPERATION_BEGIN_LAMBDA,
|
133
|
+
OPERATION_EVAL_EXPRESSION,
|
134
|
+
OPERATION_EVAL_TEMPLATE_FILE,
|
135
|
+
OPERATION_EVAL_TEMPLATE_STRING,
|
136
|
+
OPERATION_INSERT_PLAIN_FILE,
|
137
|
+
]
|
145
138
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
OPERATION_EVAL_TEMPLATE_FILE,
|
151
|
-
OPERATION_EVAL_TEMPLATE_STRING,
|
152
|
-
OPERATION_INSERT_PLAIN_FILE,
|
153
|
-
]
|
139
|
+
SILENT_OPERATIONS = [
|
140
|
+
OPERATION_COMMENT_LINE,
|
141
|
+
OPERATION_BEGIN_LAMBDA,
|
142
|
+
]
|
154
143
|
|
155
|
-
|
156
|
-
OPERATION_COMMENT_LINE,
|
157
|
-
OPERATION_BEGIN_LAMBDA,
|
158
|
-
]
|
144
|
+
VOCAL_OPERATIONS = OPERATIONS - SILENT_OPERATIONS
|
159
145
|
|
160
|
-
|
146
|
+
DIRECTIVE_HEAD = '<%'
|
147
|
+
DIRECTIVE_BODY = '(?:(?#
|
148
|
+
there is nothing here, before the alternation,
|
149
|
+
because we want to match the "<%%>" base case
|
150
|
+
)|[^%](?:.(?!<%))*?)'
|
151
|
+
DIRECTIVE_TAIL = '-?%>'
|
161
152
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
153
|
+
SHORTHAND_HEAD = '%'
|
154
|
+
SHORTHAND_BODY = '(?:(?#
|
155
|
+
there is nothing here, before the alternation,
|
156
|
+
because we want to match the "<%%>" base case
|
157
|
+
)|[^%].*)'
|
158
|
+
SHORTHAND_TAIL = '$'
|
168
159
|
|
169
|
-
|
170
|
-
|
171
|
-
there is nothing here before the alternation
|
172
|
-
because we want to match the "<%%>" base case
|
173
|
-
)|[^%].*)'
|
174
|
-
SHORTHAND_TAIL = '$'
|
160
|
+
NEWLINE = '\r?\n'
|
161
|
+
SPACING = '[[:blank:]]*'
|
175
162
|
|
176
|
-
|
177
|
-
SPACING = '[[:blank:]]*'
|
163
|
+
MARGIN_REGEXP = /^#{SPACING}(?=\S)/o
|
178
164
|
|
179
|
-
|
165
|
+
LAMBDA_BEGIN_REGEXP = /\b(do)\b\s*(\|.*?\|)?\s*$/
|
180
166
|
|
181
|
-
|
167
|
+
build_keyword_regexp = lambda {|*words| /\A\s*\b(#{words.join '|'})\b/ }
|
182
168
|
|
183
|
-
|
169
|
+
BLOCK_BEGIN_REGEXP = build_keyword_regexp[
|
170
|
+
# generic
|
171
|
+
:begin,
|
184
172
|
|
185
|
-
|
186
|
-
|
187
|
-
:begin,
|
173
|
+
# conditional
|
174
|
+
:if, :unless, :case,
|
188
175
|
|
189
|
-
|
190
|
-
|
176
|
+
# loops
|
177
|
+
:for, :while, :until,
|
191
178
|
|
192
|
-
|
193
|
-
|
194
|
-
|
179
|
+
# scopes
|
180
|
+
:def, :class, :module
|
181
|
+
]
|
195
182
|
|
196
183
|
BLOCK_CONTINUE_REGEXP = build_keyword_regexp[
|
197
|
-
|
198
|
-
|
184
|
+
# generic
|
185
|
+
:rescue, :ensure,
|
199
186
|
|
200
|
-
|
201
|
-
|
202
|
-
|
187
|
+
# conditional
|
188
|
+
:else, :elsif, :when
|
189
|
+
]
|
203
190
|
|
204
|
-
BLOCK_END_REGEXP
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
#:startdoc:
|
191
|
+
BLOCK_END_REGEXP = build_keyword_regexp[
|
192
|
+
# generic
|
193
|
+
:end
|
194
|
+
]
|
210
195
|
|
211
196
|
##
|
212
197
|
# Transforms the given eRuby template into an executable Ruby program.
|
@@ -237,6 +222,9 @@ module Ember
|
|
237
222
|
template = contents.zip(directives).join
|
238
223
|
end
|
239
224
|
|
225
|
+
# convert single-line comment directives into nothing
|
226
|
+
template.gsub!(/^#{SPACING}#{DIRECTIVE_HEAD}##{DIRECTIVE_BODY}#{DIRECTIVE_TAIL}#{SPACING}$/, '')
|
227
|
+
|
240
228
|
# translate template into Ruby code
|
241
229
|
@margins = []
|
242
230
|
@crowns = []
|
@@ -593,4 +581,4 @@ module Ember
|
|
593
581
|
Statement = Struct.new :type, :value
|
594
582
|
end
|
595
583
|
end
|
596
|
-
end
|
584
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# Simple combinatorics library for Ruby 1.8, 1.9, and (hopefully) beyond.
|
2
|
+
#
|
3
|
+
# (the ISC license)
|
4
|
+
#
|
5
|
+
# Copyright 2007 Suraj N. Kurapati <sunaku@gmail.com>
|
6
|
+
#
|
7
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
# purpose with or without fee is hereby granted, provided that the above
|
9
|
+
# copyright notice and this permission notice appear in all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
12
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
13
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
14
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
15
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
16
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
17
|
+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
#
|
19
|
+
class Array
|
20
|
+
unless method_defined? :enumeration
|
21
|
+
##
|
22
|
+
# Returns all possible enumerations made from
|
23
|
+
# sample_size number of items from this list.
|
24
|
+
#
|
25
|
+
# @param [Integer] sample_size
|
26
|
+
# The length of each enumeration.
|
27
|
+
#
|
28
|
+
# @param [Proc] sampler
|
29
|
+
# If given, each enumeration is passed to this block.
|
30
|
+
#
|
31
|
+
def enumeration(sample_size = self.length, &sampler)
|
32
|
+
return [] if sample_size < 1
|
33
|
+
|
34
|
+
results = []
|
35
|
+
|
36
|
+
visitor = lambda do |parents|
|
37
|
+
each do |child|
|
38
|
+
result = parents + [child]
|
39
|
+
|
40
|
+
if result.length < sample_size
|
41
|
+
visitor.call result
|
42
|
+
else
|
43
|
+
yield result if block_given?
|
44
|
+
results << result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
visitor.call []
|
50
|
+
results
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
unless method_defined? :enumerations
|
55
|
+
##
|
56
|
+
# Returns all possible enumerations of all possible lengths.
|
57
|
+
#
|
58
|
+
# @param [Proc] sampler
|
59
|
+
# If given, each enumeration is passed to this block.
|
60
|
+
#
|
61
|
+
def enumerations &sampler
|
62
|
+
all_lengths_impl :enumeration, &sampler
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
unless method_defined? :combination
|
67
|
+
##
|
68
|
+
# Returns all possible combinations made from
|
69
|
+
# sample_size number of items from this list.
|
70
|
+
#
|
71
|
+
# @param [Integer] sample_size
|
72
|
+
# The length of each combination.
|
73
|
+
#
|
74
|
+
# @param [Proc] sampler
|
75
|
+
# If given, each combination is passed to this block.
|
76
|
+
#
|
77
|
+
def combination(sample_size = self.length, &sampler)
|
78
|
+
pnk_cnk_impl(sample_size, true, &sampler)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
unless method_defined? :combinations
|
83
|
+
##
|
84
|
+
# Returns all possible combinations of all possible lengths.
|
85
|
+
#
|
86
|
+
# @param [Proc] sampler
|
87
|
+
# If given, each combination is passed to this block.
|
88
|
+
#
|
89
|
+
def combinations &sampler
|
90
|
+
all_lengths_impl :combination, &sampler
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
unless method_defined? :permutation
|
95
|
+
##
|
96
|
+
# Returns all possible permutations made from
|
97
|
+
# sample_size number of items from this list.
|
98
|
+
#
|
99
|
+
# @param [Integer] sample_size
|
100
|
+
# The length of each permutation.
|
101
|
+
#
|
102
|
+
# @param [Proc] sampler
|
103
|
+
# If given, each permutation is passed to this block.
|
104
|
+
#
|
105
|
+
def permutation(sample_size = self.length, &sampler)
|
106
|
+
pnk_cnk_impl(sample_size, false, &sampler)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
unless method_defined? :permutations
|
111
|
+
##
|
112
|
+
# Returns all possible permutations of all possible lengths.
|
113
|
+
#
|
114
|
+
# @param [Proc] sampler
|
115
|
+
# If given, each permutation is passed to this block.
|
116
|
+
#
|
117
|
+
def permutations &sampler
|
118
|
+
all_lengths_impl :permutation, &sampler
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
##
|
125
|
+
# Returns results of the given method name for all possible sample sizes.
|
126
|
+
#
|
127
|
+
def all_lengths_impl method_name, &sampler
|
128
|
+
results = []
|
129
|
+
|
130
|
+
0.upto(length) do |i|
|
131
|
+
results << __send__(method_name, i, &sampler)
|
132
|
+
end
|
133
|
+
|
134
|
+
results
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# Common implementation for permutation and combination functions.
|
139
|
+
#
|
140
|
+
# @param [Integer] sample_size
|
141
|
+
# Maximum depth of traversal, at which point to stop
|
142
|
+
# further traversal and to start collecting results.
|
143
|
+
#
|
144
|
+
# @param [boolean] exclude_parents
|
145
|
+
# Prevent already visited vertices from being
|
146
|
+
# visited again in subsequent iterations?
|
147
|
+
#
|
148
|
+
def pnk_cnk_impl sample_size, exclude_parents
|
149
|
+
results = []
|
150
|
+
|
151
|
+
if sample_size >= 0 && sample_size < self.length
|
152
|
+
##
|
153
|
+
# @param [#each] parents
|
154
|
+
# list of visited vertices, including the current vertex
|
155
|
+
#
|
156
|
+
# @param [#each] children
|
157
|
+
# list of unvisited vertices adjacent to current vertex
|
158
|
+
#
|
159
|
+
# @param [Integer] depth
|
160
|
+
# current depth of the traversal tree
|
161
|
+
#
|
162
|
+
visitor = lambda do |parents, children, depth|
|
163
|
+
# traverse the graph until we reach the fringe
|
164
|
+
# vertices (leaf nodes of the traversal tree)
|
165
|
+
if depth < sample_size - 1
|
166
|
+
children.each do |c|
|
167
|
+
next_children = children - (exclude_parents ? parents : [c])
|
168
|
+
next_parents = parents + [c]
|
169
|
+
next_depth = depth + 1
|
170
|
+
|
171
|
+
visitor.call next_parents, next_children, next_depth
|
172
|
+
end
|
173
|
+
else
|
174
|
+
# now we have reached the fringe vertices
|
175
|
+
children.each do |c|
|
176
|
+
result = parents + [c]
|
177
|
+
yield result if block_given?
|
178
|
+
results << result
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
visitor.call [], self, 0
|
184
|
+
end
|
185
|
+
|
186
|
+
results
|
187
|
+
end
|
188
|
+
end
|