tins 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/Gemfile +2 -0
- data/README.md +25 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/examples/bb3.stm +15 -15
- data/examples/concatenate_compare.mtm +26 -26
- data/examples/length_difference.mtm +12 -12
- data/examples/let.rb +2 -2
- data/examples/ones_difference.mtm +7 -7
- data/examples/ones_difference.stm +19 -19
- data/examples/prefix-equals-suffix-reversed-with-infix.stm +33 -33
- data/examples/recipe_common.rb +0 -32
- data/lib/tins.rb +1 -2
- data/lib/tins/annotate.rb +1 -1
- data/lib/tins/ask_and_send.rb +16 -0
- data/lib/tins/case_predicate.rb +7 -0
- data/lib/tins/dslkit.rb +7 -54
- data/lib/tins/file_binary.rb +1 -3
- data/lib/tins/method_description.rb +4 -2
- data/lib/tins/null.rb +1 -1
- data/lib/tins/string_version.rb +1 -3
- data/lib/tins/terminal.rb +18 -10
- data/lib/tins/thread_local.rb +2 -3
- data/lib/tins/token.rb +4 -1
- data/lib/tins/version.rb +1 -1
- data/lib/tins/xt.rb +2 -1
- data/lib/tins/xt/case_predicate.rb +8 -0
- data/lib/tins/xt/dslkit.rb +0 -1
- data/lib/tins/xt/named.rb +14 -26
- data/lib/tins/{time_freezer.rb → xt/time_freezer.rb} +0 -0
- data/tests/ask_and_send_test.rb +14 -0
- data/tests/attempt_test.rb +0 -6
- data/tests/case_predicate_test.rb +29 -0
- data/tests/dslkit_test.rb +0 -2
- data/tests/if_predicate_test.rb +1 -1
- data/tests/method_description_test.rb +15 -2
- data/tests/test_helper.rb +4 -0
- data/tins.gemspec +7 -7
- metadata +23 -28
- data/examples/bb3_19.stm +0 -26
- data/examples/concatenate_compare_19.mtm +0 -31
- data/examples/length_difference_19.mtm +0 -17
- data/examples/ones_difference_19.mtm +0 -12
- data/examples/ones_difference_19.stm +0 -25
- data/examples/prefix-equals-suffix-reversed-with-infix_19.stm +0 -38
- data/lib/tins/round.rb +0 -51
- data/lib/tins/xt/round.rb +0 -13
- data/tests/round_test.rb +0 -32
data/lib/tins/dslkit.rb
CHANGED
@@ -12,14 +12,10 @@ module Tins
|
|
12
12
|
#
|
13
13
|
# The module can be included into other modules/classes to make the methods available.
|
14
14
|
module Eigenclass
|
15
|
-
|
16
|
-
|
17
|
-
else
|
18
|
-
# Returns the eigenclass of this object.
|
19
|
-
def eigenclass
|
20
|
-
class << self; self; end
|
21
|
-
end
|
15
|
+
# Returns the eigenclass of this object.
|
16
|
+
def eigenclass
|
22
17
|
end
|
18
|
+
alias eigenclass singleton_class
|
23
19
|
|
24
20
|
# Evaluates the _block_ in context of the eigenclass of this object.
|
25
21
|
def eigenclass_eval(&block)
|
@@ -30,8 +26,7 @@ module Tins
|
|
30
26
|
module ClassMethod
|
31
27
|
include Eigenclass
|
32
28
|
|
33
|
-
# Define a class method named _name_ using _block_.
|
34
|
-
# blocks as arguments in the given _block_ Ruby 1.9 is required.
|
29
|
+
# Define a class method named _name_ using _block_.
|
35
30
|
def class_define_method(name, &block)
|
36
31
|
eigenclass_eval { define_method(name, &block) }
|
37
32
|
end
|
@@ -92,55 +87,13 @@ module Tins
|
|
92
87
|
end
|
93
88
|
|
94
89
|
module InstanceExec
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
attr_accessor :count
|
99
|
-
end
|
100
|
-
self.count = 0
|
101
|
-
self.pool = []
|
102
|
-
|
103
|
-
# This is a pure ruby implementation of Ruby 1.9's instance_exec method. It
|
104
|
-
# executes _block_ in the context of this object while parsing <i>*args</i> into
|
105
|
-
# the block.
|
106
|
-
def instance_exec(*args, &block)
|
107
|
-
instance = self
|
108
|
-
id = instance_exec_fetch_symbol
|
109
|
-
InstanceExec.module_eval do
|
110
|
-
begin
|
111
|
-
define_method id, block
|
112
|
-
instance.__send__ id, *args
|
113
|
-
ensure
|
114
|
-
remove_method id if method_defined?(id)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
ensure
|
118
|
-
InstanceExec.pool << id
|
119
|
-
end
|
120
|
-
|
121
|
-
private
|
122
|
-
|
123
|
-
@@mutex = Mutex.new
|
124
|
-
|
125
|
-
# Fetch a symbol from a pool in thread save way. If no more symbols are
|
126
|
-
# available create a new one, that will be pushed into the pool later.
|
127
|
-
def instance_exec_fetch_symbol
|
128
|
-
@@mutex.synchronize do
|
129
|
-
if InstanceExec.pool.empty?
|
130
|
-
InstanceExec.count += 1
|
131
|
-
symbol = :"__instance_exec_#{InstanceExec.count}__"
|
132
|
-
else
|
133
|
-
symbol = InstanceExec.pool.shift
|
134
|
-
end
|
135
|
-
return symbol
|
136
|
-
end
|
137
|
-
end
|
90
|
+
def self.included(*)
|
91
|
+
super
|
92
|
+
warn "#{self} is deprecated, but included at #{caller.first[/(.*):/, 1]}"
|
138
93
|
end
|
139
94
|
end
|
140
95
|
|
141
96
|
module Interpreter
|
142
|
-
include InstanceExec
|
143
|
-
|
144
97
|
# Interpret the string _source_ as a body of a block, while passing
|
145
98
|
# <i>*args</i> into the block.
|
146
99
|
#
|
data/lib/tins/file_binary.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'tins/xt/hash_union'
|
2
|
-
|
3
1
|
module Tins
|
4
2
|
module FileBinary
|
5
3
|
module Constants
|
@@ -35,7 +33,7 @@ module Tins
|
|
35
33
|
# from offset <tt>options[:offset]</tt>). If an option isn't given the one
|
36
34
|
# from FileBinary.default_options is used instead.
|
37
35
|
def binary?(options = {})
|
38
|
-
options
|
36
|
+
options = FileBinary.default_options.merge(options)
|
39
37
|
old_pos = tell
|
40
38
|
seek options[:offset], Constants::SEEK_SET
|
41
39
|
data = read options[:buffer_size]
|
@@ -3,7 +3,7 @@ module Tins
|
|
3
3
|
def description
|
4
4
|
result = ''
|
5
5
|
if owner <= Module
|
6
|
-
result << receiver.to_s << '.'
|
6
|
+
result << receiver.to_s << '.' # XXX Better to use owner here as well?
|
7
7
|
else
|
8
8
|
result << owner.name.to_s << '#'
|
9
9
|
end
|
@@ -22,8 +22,10 @@ module Tins
|
|
22
22
|
when :req
|
23
23
|
p_name
|
24
24
|
when :opt
|
25
|
-
"#{p_name}
|
25
|
+
"#{p_name}=?"
|
26
26
|
when :key
|
27
|
+
"#{p_name}:?"
|
28
|
+
when :keyreq
|
27
29
|
"#{p_name}:"
|
28
30
|
else
|
29
31
|
[ p_name, p_type ] * ':'
|
data/lib/tins/null.rb
CHANGED
data/lib/tins/string_version.rb
CHANGED
data/lib/tins/terminal.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'tins/xt/ask_and_send'
|
2
|
-
|
3
1
|
begin
|
4
2
|
require 'io/console'
|
5
3
|
rescue LoadError
|
@@ -10,11 +8,23 @@ module Tins
|
|
10
8
|
|
11
9
|
module_function
|
12
10
|
|
11
|
+
def winsize
|
12
|
+
if IO.respond_to?(:console)
|
13
|
+
console = IO.console
|
14
|
+
if console.respond_to?(:winsize)
|
15
|
+
console.winsize
|
16
|
+
else
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
else
|
20
|
+
[]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
13
25
|
def rows
|
14
|
-
|
15
|
-
`
|
16
|
-
`tput lines 2>/dev/null`.to_i.nonzero? ||
|
17
|
-
25
|
26
|
+
winsize[0] || `stty size 2>/dev/null`.split[0].to_i.nonzero? ||
|
27
|
+
`tput lines 2>/dev/null`.to_i.nonzero? || 25
|
18
28
|
end
|
19
29
|
|
20
30
|
def lines
|
@@ -22,10 +32,8 @@ module Tins
|
|
22
32
|
end
|
23
33
|
|
24
34
|
def columns
|
25
|
-
|
26
|
-
`
|
27
|
-
`tput cols 2>/dev/null`.to_i.nonzero? ||
|
28
|
-
80
|
35
|
+
winsize[1] || `stty size 2>/dev/null`.split[1].to_i.nonzero? ||
|
36
|
+
`tput cols 2>/dev/null`.to_i.nonzero? || 80
|
29
37
|
end
|
30
38
|
|
31
39
|
def cols
|
data/lib/tins/thread_local.rb
CHANGED
@@ -41,11 +41,10 @@ module Tins
|
|
41
41
|
# Define a thread local variable for the current instance with name _name_.
|
42
42
|
# If the value _value_ is given, it is used to initialize the variable.
|
43
43
|
def instance_thread_local(name, value = nil)
|
44
|
-
|
44
|
+
class << self
|
45
45
|
extend Tins::ThreadLocal
|
46
46
|
self
|
47
|
-
end
|
48
|
-
sc.thread_local name, value
|
47
|
+
end.thread_local name, value
|
49
48
|
self
|
50
49
|
end
|
51
50
|
end
|
data/lib/tins/token.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Tins
|
2
4
|
class Token < String
|
3
5
|
DEFAULT_ALPHABET = ((?0..?9).to_a + (?a..?z).to_a + (?A..?Z).to_a).freeze
|
@@ -7,6 +9,7 @@ module Tins
|
|
7
9
|
bits = options[:bits] || 128
|
8
10
|
length = options[:length]
|
9
11
|
alphabet = options[:alphabet] || DEFAULT_ALPHABET
|
12
|
+
random = options[:random] || SecureRandom
|
10
13
|
alphabet.size > 1 or raise ArgumentError, 'need at least 2 symbols in alphabet'
|
11
14
|
if length
|
12
15
|
length > 0 or raise ArgumentError, 'length has to be positive'
|
@@ -16,7 +19,7 @@ module Tins
|
|
16
19
|
end
|
17
20
|
self.bits = (Math.log(alphabet.size ** length) / Math.log(2)).floor
|
18
21
|
token = ''
|
19
|
-
length.times { token << alphabet[
|
22
|
+
length.times { token << alphabet[random.random_number(alphabet.size)] }
|
20
23
|
super token
|
21
24
|
end
|
22
25
|
|
data/lib/tins/version.rb
CHANGED
data/lib/tins/xt.rb
CHANGED
@@ -16,7 +16,6 @@ module Tins
|
|
16
16
|
require 'tins/xt/partial_application'
|
17
17
|
require 'tins/xt/range_plus'
|
18
18
|
require 'tins/xt/require_maybe'
|
19
|
-
require 'tins/xt/round'
|
20
19
|
require 'tins/xt/secure_write'
|
21
20
|
require 'tins/xt/string'
|
22
21
|
require 'tins/xt/subhash'
|
@@ -40,4 +39,6 @@ module Tins
|
|
40
39
|
require 'tins/xt/annotate'
|
41
40
|
require 'tins/xt/concern'
|
42
41
|
require 'tins/xt/dslkit'
|
42
|
+
require 'tins/xt/time_freezer'
|
43
|
+
require 'tins/xt/case_predicate'
|
43
44
|
end
|
data/lib/tins/xt/dslkit.rb
CHANGED
data/lib/tins/xt/named.rb
CHANGED
@@ -1,35 +1,23 @@
|
|
1
1
|
require 'tins/xt/string_version'
|
2
2
|
|
3
3
|
class Object
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
}
|
12
|
-
end
|
13
|
-
else
|
14
|
-
def named(name, method, *args, &block)
|
15
|
-
extend Module.new { define_method(name) { |*rest| __send__(method, *(args + rest), &block) } }
|
16
|
-
end
|
4
|
+
def named(name, method, *args, &named_block)
|
5
|
+
extend Module.new {
|
6
|
+
define_method(name) do |*rest, &block|
|
7
|
+
block = named_block if named_block
|
8
|
+
__send__(method, *(args + rest), &block)
|
9
|
+
end
|
10
|
+
}
|
17
11
|
end
|
18
12
|
end
|
19
13
|
|
20
14
|
class Module
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
}
|
29
|
-
end
|
30
|
-
else
|
31
|
-
def named(name, method, *args, &block)
|
32
|
-
include Module.new { define_method(name) { |*rest| __send__(method, *(args + rest), &block) } }
|
33
|
-
end
|
15
|
+
def named(name, method, *args, &named_block)
|
16
|
+
include Module.new {
|
17
|
+
define_method(name) do |*rest, &block|
|
18
|
+
block = named_block if named_block
|
19
|
+
__send__(method, *(args + rest), &block)
|
20
|
+
end
|
21
|
+
}
|
34
22
|
end
|
35
23
|
end
|
File without changes
|
data/tests/ask_and_send_test.rb
CHANGED
@@ -28,5 +28,19 @@ module Tins
|
|
28
28
|
assert_equal :bar, A.new.ask_and_send!(:bar)
|
29
29
|
assert_nil A.new.ask_and_send(:baz)
|
30
30
|
end
|
31
|
+
|
32
|
+
def test_asking_selfy_publicly
|
33
|
+
a = A.new
|
34
|
+
assert_equal :foo, a.ask_and_send_or_self(:foo)
|
35
|
+
assert_equal a, a.ask_and_send_or_self(:bar)
|
36
|
+
assert_equal a, a.ask_and_send_or_self(:baz)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_asking_selfy_privately
|
40
|
+
a = A.new
|
41
|
+
assert_equal :foo, a.ask_and_send_or_self!(:foo)
|
42
|
+
assert_equal :bar, a.ask_and_send_or_self!(:bar)
|
43
|
+
assert_equal a, a.ask_and_send_or_self(:baz)
|
44
|
+
end
|
31
45
|
end
|
32
46
|
end
|
data/tests/attempt_test.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'tins/xt/case_predicate'
|
3
|
+
|
4
|
+
module Tins
|
5
|
+
class CasePredicateTest < Test::Unit::TestCase
|
6
|
+
def test_case_predicate_failure
|
7
|
+
assert_nil 4.case?(1, 2..3, 5...7)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_case_predicate_failure_is_a
|
11
|
+
s = 'foo'
|
12
|
+
assert_nil s.case?(Array, Hash)
|
13
|
+
s = Class.new(String).new
|
14
|
+
assert_nil s.case?(Array, Hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_case_predicate_success
|
18
|
+
assert_equal 2..3, 3.case?(1, 2..3, 5...7)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_case_predicate_success_is_a
|
22
|
+
s = 'foo'
|
23
|
+
assert_equal String, s.case?(Array, Hash, String)
|
24
|
+
s = Class.new(String).new
|
25
|
+
assert_equal String, s.case?(Array, Hash, String)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/tests/dslkit_test.rb
CHANGED
data/tests/if_predicate_test.rb
CHANGED
@@ -25,7 +25,7 @@ if RUBY_VERSION >= "1.9"
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_standard_parameters
|
28
|
-
assert_equal 'Tins::MethodDescriptionTest::B#foo(x,y
|
28
|
+
assert_equal 'Tins::MethodDescriptionTest::B#foo(x,y=?,*r,&b)', B.instance_method(:foo).to_s
|
29
29
|
end
|
30
30
|
|
31
31
|
if RUBY_VERSION >= "2.0"
|
@@ -39,11 +39,24 @@ if RUBY_VERSION >= "1.9"
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def test_keyword_parameters
|
42
|
-
assert_equal 'Tins::MethodDescriptionTest::C#foo(x,k
|
42
|
+
assert_equal 'Tins::MethodDescriptionTest::C#foo(x,k:?,&b)', C.instance_method(:foo).to_s
|
43
43
|
assert_equal 'Tins::MethodDescriptionTest::C#bar(x,**k,&b)', C.instance_method(:bar).to_s
|
44
44
|
end
|
45
45
|
}
|
46
46
|
end
|
47
|
+
|
48
|
+
if RUBY_VERSION >= "2.1"
|
49
|
+
eval %{
|
50
|
+
class D
|
51
|
+
def foo(x, k:, &b)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_keyword_parameters_required
|
56
|
+
assert_equal 'Tins::MethodDescriptionTest::D#foo(x,k:,&b)', D.instance_method(:foo).to_s
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
47
60
|
end
|
48
61
|
end
|
49
62
|
end
|