shen-ruby 0.10.0 → 0.11.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.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +9 -3
  4. data/Gemfile +1 -4
  5. data/HISTORY.md +16 -0
  6. data/MIT_LICENSE.txt +1 -1
  7. data/README.md +25 -26
  8. data/Rakefile +3 -11
  9. data/bin/shen_test_suite.rb +15 -3
  10. data/bin/srrepl +6 -8
  11. data/lib/shen_ruby.rb +6 -1
  12. data/lib/shen_ruby/converters.rb +23 -0
  13. data/lib/shen_ruby/version.rb +1 -1
  14. data/shen-ruby.gemspec +4 -1
  15. data/shen/lib/shen_ruby/shen.rb +49 -33
  16. data/shen/release/benchmarks/N_queens.shen +45 -45
  17. data/shen/release/benchmarks/README.shen +14 -14
  18. data/shen/release/benchmarks/benchmarks.shen +52 -52
  19. data/shen/release/benchmarks/einstein.shen +32 -32
  20. data/shen/release/benchmarks/interpreter.shen +219 -219
  21. data/shen/release/benchmarks/jnk.shen +193 -193
  22. data/shen/release/benchmarks/powerset.shen +10 -10
  23. data/shen/release/benchmarks/prime.shen +10 -10
  24. data/shen/release/benchmarks/short.shen +129 -129
  25. data/shen/release/k_lambda/core.kl +181 -181
  26. data/shen/release/k_lambda/declarations.kl +131 -131
  27. data/shen/release/k_lambda/load.kl +84 -84
  28. data/shen/release/k_lambda/macros.kl +112 -112
  29. data/shen/release/k_lambda/prolog.kl +252 -252
  30. data/shen/release/k_lambda/reader.kl +222 -222
  31. data/shen/release/k_lambda/sequent.kl +166 -166
  32. data/shen/release/k_lambda/sys.kl +271 -271
  33. data/shen/release/k_lambda/t-star.kl +139 -139
  34. data/shen/release/k_lambda/toplevel.kl +135 -135
  35. data/shen/release/k_lambda/track.kl +103 -103
  36. data/shen/release/k_lambda/types.kl +324 -324
  37. data/shen/release/k_lambda/writer.kl +105 -105
  38. data/shen/release/k_lambda/yacc.kl +113 -113
  39. data/shen/release/test_programs/Chap13/problems.txt +26 -26
  40. data/shen/release/test_programs/README.shen +52 -52
  41. data/shen/release/test_programs/TinyLispFunctions.txt +15 -15
  42. data/shen/release/test_programs/TinyTypes.shen +55 -55
  43. data/shen/release/test_programs/binary.shen +24 -24
  44. data/shen/release/test_programs/bubble_version_1.shen +28 -28
  45. data/shen/release/test_programs/bubble_version_2.shen +22 -22
  46. data/shen/release/test_programs/calculator.shen +21 -21
  47. data/shen/release/test_programs/cartprod.shen +23 -23
  48. data/shen/release/test_programs/change.shen +25 -25
  49. data/shen/release/test_programs/classes-defaults.shen +94 -94
  50. data/shen/release/test_programs/classes-inheritance.shen +100 -100
  51. data/shen/release/test_programs/classes-typed.shen +74 -74
  52. data/shen/release/test_programs/classes-untyped.shen +46 -46
  53. data/shen/release/test_programs/depth_.shen +14 -14
  54. data/shen/release/test_programs/einstein.shen +34 -34
  55. data/shen/release/test_programs/fruit_machine.shen +46 -46
  56. data/shen/release/test_programs/interpreter.shen +217 -217
  57. data/shen/release/test_programs/metaprog.shen +85 -85
  58. data/shen/release/test_programs/minim.shen +192 -192
  59. data/shen/release/test_programs/mutual.shen +11 -11
  60. data/shen/release/test_programs/n_queens.shen +45 -45
  61. data/shen/release/test_programs/newton_version_1.shen +33 -33
  62. data/shen/release/test_programs/newton_version_2.shen +24 -24
  63. data/shen/release/test_programs/parse.prl +14 -14
  64. data/shen/release/test_programs/parser.shen +51 -51
  65. data/shen/release/test_programs/powerset.shen +10 -10
  66. data/shen/release/test_programs/prime.shen +10 -10
  67. data/shen/release/test_programs/prolog.shen +78 -78
  68. data/shen/release/test_programs/proof_assistant.shen +80 -80
  69. data/shen/release/test_programs/proplog_version_1.shen +25 -25
  70. data/shen/release/test_programs/proplog_version_2.shen +27 -27
  71. data/shen/release/test_programs/qmachine.shen +66 -66
  72. data/shen/release/test_programs/red-black.shen +54 -54
  73. data/shen/release/test_programs/search.shen +55 -55
  74. data/shen/release/test_programs/semantic_net.shen +44 -44
  75. data/shen/release/test_programs/spreadsheet.shen +34 -34
  76. data/shen/release/test_programs/stack.shen +27 -27
  77. data/shen/release/test_programs/streams.shen +20 -20
  78. data/shen/release/test_programs/strings.shen +57 -57
  79. data/shen/release/test_programs/structures-typed.shen +71 -71
  80. data/shen/release/test_programs/structures-untyped.shen +41 -41
  81. data/shen/release/test_programs/tests.shen +232 -232
  82. data/shen/release/test_programs/types.shen +11 -11
  83. data/shen/release/test_programs/whist.shen +239 -239
  84. data/shen/release/test_programs/yacc.shen +132 -132
  85. data/spec/shen_ruby/converters_spec.rb +48 -0
  86. data/spec/spec_helper.rb +1 -2
  87. metadata +55 -60
  88. data/k_lambda_spec/atom_spec.rb +0 -85
  89. data/k_lambda_spec/primitives/arithmetic_spec.rb +0 -175
  90. data/k_lambda_spec/primitives/assignments_spec.rb +0 -44
  91. data/k_lambda_spec/primitives/boolean_operations_spec.rb +0 -136
  92. data/k_lambda_spec/primitives/generic_functions_spec.rb +0 -120
  93. data/k_lambda_spec/primitives/lists_spec.rb +0 -40
  94. data/k_lambda_spec/primitives/strings_spec.rb +0 -77
  95. data/k_lambda_spec/primitives/symbols_spec.rb +0 -24
  96. data/k_lambda_spec/primitives/vectors_spec.rb +0 -92
  97. data/k_lambda_spec/spec_helper.rb +0 -29
  98. data/k_lambda_spec/support/shared_examples.rb +0 -124
  99. data/k_lambda_spec/tail_recursion_spec.rb +0 -30
  100. data/lib/kl.rb +0 -7
  101. data/lib/kl/absvector.rb +0 -12
  102. data/lib/kl/compiler.rb +0 -360
  103. data/lib/kl/cons.rb +0 -51
  104. data/lib/kl/empty_list.rb +0 -12
  105. data/lib/kl/environment.rb +0 -163
  106. data/lib/kl/error.rb +0 -4
  107. data/lib/kl/internal_error.rb +0 -7
  108. data/lib/kl/lexer.rb +0 -186
  109. data/lib/kl/primitives/arithmetic.rb +0 -60
  110. data/lib/kl/primitives/assignments.rb +0 -15
  111. data/lib/kl/primitives/booleans.rb +0 -21
  112. data/lib/kl/primitives/error_handling.rb +0 -13
  113. data/lib/kl/primitives/extensions.rb +0 -12
  114. data/lib/kl/primitives/generic_functions.rb +0 -29
  115. data/lib/kl/primitives/lists.rb +0 -23
  116. data/lib/kl/primitives/streams.rb +0 -28
  117. data/lib/kl/primitives/strings.rb +0 -63
  118. data/lib/kl/primitives/symbols.rb +0 -18
  119. data/lib/kl/primitives/time.rb +0 -17
  120. data/lib/kl/primitives/vectors.rb +0 -36
  121. data/lib/kl/reader.rb +0 -46
  122. data/spec/kl/cons_spec.rb +0 -12
  123. data/spec/kl/environment_spec.rb +0 -282
  124. data/spec/kl/interop_spec.rb +0 -68
  125. data/spec/kl/lexer_spec.rb +0 -149
  126. data/spec/kl/primitives/generic_functions_spec.rb +0 -29
  127. data/spec/kl/primitives/symbols_spec.rb +0 -21
  128. data/spec/kl/reader_spec.rb +0 -42
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for lists' do
4
- describe '(cons Hd Tl)' do
5
- it 'creates a list with Hd as the head and Tl as the tail' do
6
- kl_eval('(cons a ())').should be_kind_of Kl::Cons
7
- kl_eval('(hd (cons a ()))').should == :a
8
- kl_eval('(tl (cons a (cons b ())))').should == kl_eval('(cons b ())')
9
- end
10
-
11
- it 'allows Tl to be a non-list' do
12
- kl_eval('(tl (cons a b))').should == :b
13
- end
14
-
15
- include_examples 'partially-applicable function', %w(cons a b)
16
- include_examples 'applicative order evaluation', %w(cons a b)
17
- end
18
-
19
- describe '(hd L)' do
20
- it 'returns the head of L' do
21
- kl_eval('(hd (cons a b))').should == :a
22
- end
23
-
24
- include_examples 'argument types', [:hd, "(cons a b)"], 1 => [:list, :dotted_pair]
25
- include_examples 'partially-applicable function', [:hd, "(cons a b)"]
26
- end
27
-
28
- describe '(tl L)' do
29
- it 'returns the tail of L' do
30
- kl_eval('(tl (cons a b))').should == :b
31
- end
32
-
33
- include_examples 'argument types', [:tl, "(cons a b)"], 1 => [:list, :dotted_pair]
34
- include_examples 'partially-applicable function', [:tl, "(cons a b)"]
35
- end
36
-
37
- describe 'cons?' do
38
- include_examples 'type predicate', 'cons?', [:list, :dotted_pair]
39
- end
40
- end
@@ -1,77 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for strings' do
4
- describe '(pos S N)' do
5
- it 'returns the character at zero-based index N of S as a unit string' do
6
- kl_eval('(pos "ABC" 1)').should == "B"
7
- end
8
-
9
- it 'raises an error if N is negative' do
10
- expect {
11
- kl_eval('(pos "ABC" -1)')
12
- }.to raise_error(Kl::Error, "out of bounds")
13
- end
14
-
15
- it 'raises an error if N is >= the length of S' do
16
- expect {
17
- kl_eval('(pos "ABC" 3)')
18
- }.to raise_error(Kl::Error, "out of bounds")
19
- expect {
20
- kl_eval('(pos "ABC" 99)')
21
- }.to raise_error(Kl::Error, "out of bounds")
22
- end
23
-
24
- include_examples 'argument types', %w(pos "string" 1),
25
- 1 => [:string],
26
- 2 => [:integer]
27
- include_examples 'partially-applicable function', %w(pos "string" 1)
28
- include_examples 'applicative order evaluation', %w(pos "string" 1)
29
- end
30
-
31
- describe '(tlstr S)' do
32
- it 'returns a string containing all but the first character of S' do
33
- kl_eval('(tlstr "string")').should == "tring"
34
- end
35
-
36
- it 'raises an error when S is the empty string' do
37
- expect {
38
- kl_eval('(tlstr "")')
39
- }.to raise_error(Kl::Error, 'attempted to take tail of an empty string')
40
- end
41
-
42
- include_examples 'argument types', %w(tlstr "string"), 1 => [:string]
43
- include_examples 'partially-applicable function', %w(tlstr "string")
44
- end
45
-
46
- describe 'string?' do
47
- include_examples 'type predicate', 'string?', [:string]
48
- end
49
-
50
- describe '(n->string N)' do
51
- it 'returns a unit string containing the character with ASCII code N' do
52
- kl_eval('(n->string 65)').should == "A"
53
- end
54
-
55
- include_examples 'argument types', %w(n->string 65), 1 => [:integer]
56
- include_examples 'partially-applicable function', %w(n->string 65)
57
- end
58
-
59
- describe '(string->n S)' do
60
- it 'returns the ASCII code of the unit string S' do
61
- kl_eval('(string->n "A")').should == 65
62
- end
63
-
64
- it 'returns the ASCII code of the first character of non-unit string S' do
65
- kl_eval('(string->n "AB")').should == 65
66
- end
67
-
68
- it 'raises an error when S is the empty string' do
69
- expect {
70
- kl_eval('(string->n "")')
71
- }.to raise_error(Kl::Error, 'attempted to get code point of empty string')
72
- end
73
-
74
- include_examples 'argument types', %w(string->n "A"), 1 => [:string]
75
- include_examples 'partially-applicable function', %w(string->n "A")
76
- end
77
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for symbols' do
4
- describe 'intern' do
5
- it 'converts a string to its corresponding symbol' do
6
- kl_eval('(intern "foo")').should == :foo
7
- end
8
-
9
- it 'supports characters not allowed in symbol literals' do
10
- kl_eval('(intern "[{|}]")').should == :"[{|}]"
11
- end
12
-
13
- it 'converts the string "true" to boolean true' do
14
- kl_eval('(intern "true")').should == true
15
- end
16
-
17
- it 'converts the string "false" to boolean false' do
18
- kl_eval('(intern "false")').should == false
19
- end
20
-
21
- include_examples 'argument types', %w(intern "foo"), 1 => [:string]
22
- include_examples 'partially-applicable function', %w(intern "foo")
23
- end
24
- end
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitive functions for vectors' do
4
- describe '(absvector N)' do
5
- it 'returns a new absolute vector of size N' do
6
- kl_eval('(absvector 3)').should be_kind_of Kl::Absvector
7
- end
8
-
9
- include_examples 'argument types', %w(absvector 7), 1 => [:integer]
10
- include_examples 'partially-applicable function', %w(absvector 7)
11
- end
12
-
13
- describe '(address-> V N Value)' do
14
- before(:each) do
15
- kl_eval('(set *vec* (absvector 5))')
16
- end
17
-
18
- it 'returns the vector V updated with Value at index N' do
19
- kl_eval('(address-> (value *vec*) 3 37)').should be_kind_of Kl::Absvector
20
- kl_eval('(<-address (value *vec*) 3)').should == 37
21
- end
22
-
23
- it 'raises an error if N is negative' do
24
- expect {
25
- kl_eval('(address-> (value *vec*) -1 37)')
26
- }.to raise_error(Kl::Error, "out of bounds")
27
- end
28
-
29
- it 'raises an error if N is >= the size of the vector' do
30
- expect {
31
- kl_eval('(address-> (value *vec*) 5 37)')
32
- }.to raise_error(Kl::Error, "out of bounds")
33
- expect {
34
- kl_eval('(address-> (value *vec*) 99 37)')
35
- }.to raise_error(Kl::Error, "out of bounds")
36
- end
37
-
38
- include_examples 'argument types',
39
- ['address->', '(value *vec*)', '0', '37'],
40
- 1 => [:vector],
41
- 2 => [:integer]
42
- include_examples 'partially-applicable function',
43
- ['address->', '(value *vec*)', '0', '37']
44
- include_examples 'applicative order evaluation',
45
- ['address->', '(value *vec*)', '0', '37']
46
- end
47
-
48
- describe '(<-address V N)' do
49
- before(:each) do
50
- kl_eval('(set *vec* (absvector 5))')
51
- end
52
-
53
- it 'returns the value previously stored at index N in V' do
54
- kl_eval('(address-> (value *vec*) 3 37)')
55
- kl_eval('(<-address (value *vec*) 3)').should == 37
56
- end
57
-
58
- it 'returns an unspecified value if index N has not been stored to' do
59
- expect {
60
- kl_eval('(<-address (value *vec*) 3)')
61
- }.to_not raise_error
62
- end
63
-
64
- it 'raises an error if N is negative' do
65
- expect {
66
- kl_eval('(<-address (value *vec*) -1)')
67
- }.to raise_error(Kl::Error, "out of bounds")
68
- end
69
-
70
- it 'raises an error if N is >= the size of the vector' do
71
- expect {
72
- kl_eval('(<-address (value *vec*) 5)')
73
- }.to raise_error(Kl::Error, "out of bounds")
74
- expect {
75
- kl_eval('(<-address (value *vec*) 99)')
76
- }.to raise_error(Kl::Error, "out of bounds")
77
- end
78
-
79
- include_examples 'argument types',
80
- ['<-address', '(value *vec*)', '0'],
81
- 1 => [:vector],
82
- 2 => [:integer]
83
- include_examples 'partially-applicable function',
84
- ['address->', '(value *vec*)', '0', '37']
85
- include_examples 'applicative order evaluation',
86
- ['address->', '(value *vec*)', '0', '37']
87
- end
88
-
89
- describe 'absvector?' do
90
- include_examples 'type predicate', 'absvector?', [:vector]
91
- end
92
- end
@@ -1,29 +0,0 @@
1
- lib_path = File.expand_path("../../lib", __FILE__)
2
- $LOAD_PATH << lib_path unless $LOAD_PATH.include?(lib_path)
3
-
4
- require 'kl'
5
- require 'stringio'
6
-
7
- # Load the support files
8
- Dir["./k_lambda_spec/support/**/*.rb"].sort.each {|f| require f}
9
-
10
- # Reset the K Lambda environment before every example
11
- RSpec.configure do |config|
12
- config.before(:each) do
13
- @kl_env = Kl::Environment.new
14
- end
15
- end
16
-
17
- # Helper function that evaluates a string in the K Lambda environment and
18
- # returns the result as a Ruby object.
19
- def kl_eval(str)
20
- form = Kl::Reader.new(StringIO.new(str)).next
21
- @kl_env.__eval(form)
22
- end
23
-
24
- # Defines the 'kl-do' function in the current K Lambda environment. This is
25
- # used instead of 'do' because do is not an official K Lambda primitive
26
- # and may not be found in all K Lambda implementations.
27
- def define_kl_do
28
- kl_eval('(defun kl-do (X Y) Y)')
29
- end
@@ -1,124 +0,0 @@
1
- # args should be an array containing the components of an example expression.
2
- # E.g., to test partial application of +, you could use:
3
- #
4
- # include_examples "partially-applicable function", %w(+ 1 2)
5
- #
6
- # The expression will be evaluated in its fully-expanded form for reference
7
- # and then compared against various partial application scenarios.
8
- shared_examples "partially-applicable function" do |args|
9
- full_expression = "(#{args.join(' ')})"
10
- (0...(args.length - 1)).each do |arg_count|
11
- description = "supports partial application of #{arg_count} argument"
12
- description << "s" unless arg_count == 1
13
- it description do
14
- full_result = kl_eval(full_expression)
15
- partial_expression = "((#{args[0..arg_count].join(' ')}) #{args[(arg_count + 1)..-1].join(' ')})"
16
- kl_eval(partial_expression).should == full_result
17
- end
18
- end
19
- end
20
-
21
- shared_examples "non-partially-applicable function" do |args|
22
- (0...(args.length - 1)).each do |arg_count|
23
- description = "raises an error when given #{arg_count} argument"
24
- description << "s" unless arg_count == 1
25
- it description do
26
- partial_expression = "(#{args[0..arg_count].join(' ')})"
27
- expect {
28
- kl_eval(partial_expression)
29
- }.to raise_error(Kl::Error, "#{args[0]} expects #{args.length - 1} arguments but was given #{arg_count}")
30
- end
31
- end
32
- end
33
-
34
- # args should be an array containing the components of an example expression.
35
- # E.g., to test applicative order evaluation of +, you could use:
36
- #
37
- # include_examples "applicative order evaluation", %w(+ 1 2)
38
- shared_examples 'applicative order evaluation' do |args|
39
- it 'evaluates its arguments from left to right' do
40
- operator = args.shift
41
- arg_indexes = (0...args.size).to_a
42
- instrumented_args = args.zip(arg_indexes).map do |(arg, idx)|
43
- "(kl-do (set *arg-order* (cn (value *arg-order*) \"#{idx}\")) #{arg})"
44
- end
45
- expected = arg_indexes.join
46
-
47
- define_kl_do
48
- kl_eval('(set *arg-order* "")')
49
- kl_eval("(#{operator} #{instrumented_args.join(' ')})")
50
- kl_eval('(value *arg-order*)').should == expected
51
- end
52
- end
53
-
54
- KL_TYPE_EXAMPLES = {
55
- integer: '1',
56
- real: '1.0',
57
- string: '"a string"',
58
- symbol: 'a-symbol',
59
- boolean: 'true',
60
- list: '(cons 1 ())',
61
- dotted_pair: '(cons 1 2)',
62
- empty_list: '()',
63
- function: '(lambda X X)',
64
- vector: '(absvector 3)'
65
- }
66
-
67
- def type_with_article(type)
68
- name = type.to_s.gsub(/_/, ' ')
69
- if [:integer, :empty_list].include?(type)
70
- 'an ' + name
71
- else
72
- 'a ' + name
73
- end
74
- end
75
-
76
- shared_examples 'type predicate' do |predicate, accepted_types|
77
- accepted_types.each do |type|
78
- it "returns true when its argument is #{type_with_article(type)}" do
79
- kl_eval("(#{predicate} #{KL_TYPE_EXAMPLES[type]})").should == true
80
- end
81
- end
82
-
83
- it 'returns false when its argument is of any other type' do
84
- rejected_types = KL_TYPE_EXAMPLES.keys - accepted_types
85
- rejected_types.each do |type|
86
- kl_eval("(#{predicate} #{KL_TYPE_EXAMPLES[type]})").should == false
87
- end
88
- end
89
- end
90
-
91
- POSITION_NAMES = { 1 => 'first', 2 => 'second', 3 => 'third' }
92
-
93
- def types_to_s(types)
94
- if types.length > 2
95
- types[0..-2].map { |t| type_with_article(t) }.join(', ') +
96
- ', or ' + type_with_article(types[-1])
97
- else
98
- types.map { |t| type_with_article(t) }.join(' or ')
99
- end
100
- end
101
-
102
- shared_examples 'argument types' do |expr, accepted_argument_types|
103
- accepted_argument_types.to_a.sort.each do |(idx, accepted_types)|
104
- type_str = types_to_s(accepted_types)
105
- it "raises an error if its #{POSITION_NAMES[idx]} argument is not #{type_str}" do
106
- accepted_types.each do |type|
107
- other_expr = expr.dup
108
- other_expr[idx] = KL_TYPE_EXAMPLES[type]
109
- expect {
110
- kl_eval("(#{other_expr.join(' ')})")
111
- }.to_not raise_error
112
- end
113
-
114
- rejected_types = KL_TYPE_EXAMPLES.keys - accepted_types
115
- rejected_types.each do |type|
116
- other_expr = expr.dup
117
- other_expr[idx] = KL_TYPE_EXAMPLES[type]
118
- expect {
119
- kl_eval("(#{other_expr.join(' ')})")
120
- }.to raise_error(Kl::Error, /is not a/)
121
- end
122
- end
123
- end
124
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Tail recursion' do
4
- it 'does not consume stack space for self tail calls' do
5
- kl_eval <<-EOS
6
- (defun count-down (X)
7
- (if (= X 0)
8
- success
9
- (count-down (- X 1))))
10
- EOS
11
- kl_eval('(count-down 10000)').should == :success
12
- end
13
-
14
- it 'does not consume stack space for mutually recursive tail calls' do
15
- kl_eval <<-EOS
16
- (defun even? (X)
17
- (if (= X 1)
18
- false
19
- (odd? (- X 1))))
20
- EOS
21
- kl_eval <<-EOS
22
- (defun odd? (X)
23
- (if (= X 1)
24
- true
25
- (even? (- X 1))))
26
- EOS
27
- kl_eval('(even? 100000)').should == true
28
- kl_eval('(odd? 100000)').should == false
29
- end
30
- end
data/lib/kl.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'kl/error'
2
- require 'kl/internal_error'
3
- require 'kl/empty_list'
4
- require 'kl/cons'
5
- require 'kl/absvector'
6
- require 'kl/reader'
7
- require 'kl/environment'
data/lib/kl/absvector.rb DELETED
@@ -1,12 +0,0 @@
1
- module Kl
2
- # Absvectors are just arrays. We give them their own subclass
3
- # to support the absvector? primitive.
4
- class Absvector < Array
5
- attr_reader :upper_limit
6
-
7
- def initialize(n)
8
- super(n, :"shen.fail!")
9
- @upper_limit = n
10
- end
11
- end
12
- end