tins 1.32.1 → 1.37.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/CHANGES.md +105 -0
- data/Rakefile +2 -3
- data/examples/ones_difference.stm +0 -1
- data/lib/tins/concern.rb +36 -0
- data/lib/tins/count_by.rb +16 -3
- data/lib/tins/deep_const_get.rb +48 -34
- data/lib/tins/deprecate.rb +15 -0
- data/lib/tins/duration.rb +42 -0
- data/lib/tins/hash_bfs.rb +67 -0
- data/lib/tins/secure_write.rb +1 -1
- data/lib/tins/sexy_singleton.rb +2 -1
- data/lib/tins/string_version.rb +4 -0
- data/lib/tins/terminal.rb +3 -3
- data/lib/tins/time_dummy.rb +2 -1
- data/lib/tins/timed_cache.rb +1 -1
- data/lib/tins/token.rb +5 -1
- data/lib/tins/uniq_by.rb +16 -3
- data/lib/tins/version.rb +1 -1
- data/lib/tins/xt/count_by.rb +0 -4
- data/lib/tins/xt/deprecate.rb +5 -0
- data/lib/tins/xt/hash_bfs.rb +7 -0
- data/lib/tins/xt/uniq_by.rb +13 -3
- data/lib/tins/xt.rb +2 -0
- data/lib/tins.rb +2 -0
- data/tests/annotate_test.rb +0 -1
- data/tests/bijection_test.rb +0 -1
- data/tests/concern_test.rb +39 -2
- data/tests/date_dummy_test.rb +0 -1
- data/tests/date_time_dummy_test.rb +0 -1
- data/tests/delegate_test.rb +0 -1
- data/tests/deprecate_test.rb +41 -0
- data/tests/dslkit_test.rb +0 -1
- data/tests/duration_test.rb +19 -2
- data/tests/dynamic_scope_test.rb +0 -1
- data/tests/extract_last_argument_options_test.rb +0 -1
- data/tests/find_test.rb +0 -1
- data/tests/from_module_test.rb +0 -1
- data/tests/generator_test.rb +0 -1
- data/tests/go_test.rb +0 -1
- data/tests/hash_bfs_test.rb +34 -0
- data/tests/hash_symbolize_keys_recursive_test.rb +0 -1
- data/tests/implement_test.rb +0 -1
- data/tests/limited_test.rb +16 -1
- data/tests/lines_file_test.rb +0 -1
- data/tests/lru_cache_test.rb +0 -1
- data/tests/memoize_test.rb +0 -1
- data/tests/minimize_test.rb +0 -1
- data/tests/module_group_test.rb +0 -1
- data/tests/named_set_test.rb +0 -1
- data/tests/null_test.rb +0 -1
- data/tests/require_maybe_test.rb +0 -1
- data/tests/scope_test.rb +0 -1
- data/tests/secure_write_test.rb +6 -1
- data/tests/sexy_singleton_test.rb +1 -1
- data/tests/string_version_test.rb +1 -1
- data/tests/subhash_test.rb +0 -1
- data/tests/test_helper.rb +2 -1
- data/tests/time_dummy_test.rb +0 -1
- data/tests/time_freezer_test.rb +1 -1
- data/tests/token_test.rb +0 -1
- data/tests/unit_test.rb +0 -1
- data/tins.gemspec +16 -29
- metadata +32 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '049e3bf81de447eec53664f5555656602906bbd44a5f98b2e0e953318aadff77'
|
4
|
+
data.tar.gz: 14debef966e248366ec1ef72b39b8ccc094a91049ed6cd44e9ee2550c607ae02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c93d9b5b23c3305f422f0efd81e0828591682331532b51f4de1a84e305f77bb3f9374abcf8b725cd665a74ef352cabb525f49b4dfa68fc78f5568e87a5e78012
|
7
|
+
data.tar.gz: 4b8d5d1da5bffb1b26449f96aa0f292a28582e5409d734ba5cdc18c428a2e6b57f577662773b776abcbb5464d505ae6726b60bba54f2142ddf5a32faae5fd9e9
|
data/CHANGES.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Changes
|
2
|
+
|
3
|
+
## 2024-10-19 v1.37.0
|
4
|
+
|
5
|
+
* Add support for module prepended blocks in **Tins::Concern**:
|
6
|
+
* Added `prepend_features` method to Tins concern
|
7
|
+
* Updated ConcernTest to test prepend feature
|
8
|
+
* Raise StandardError for duplicate block definitions for included and
|
9
|
+
prepended blocks
|
10
|
+
* Added `class_methods` method to Tins concern:
|
11
|
+
* Added `class_methods` method to lib/tins/concern.rb
|
12
|
+
- Creates or retrieves ClassMethods module for defining class-level methods
|
13
|
+
* Updated tests in `tests/concern_test.rb`
|
14
|
+
- Added test for new `baz1` and `baz2` methods
|
15
|
+
+ Tested availability of `bar`, `baz1`, and `baz2` methods on A
|
16
|
+
|
17
|
+
## 2024-10-11 v1.36.1
|
18
|
+
|
19
|
+
* Fixed a typo in the code
|
20
|
+
|
21
|
+
## 2024-10-11 v1.36.0
|
22
|
+
|
23
|
+
### Significant Changes
|
24
|
+
|
25
|
+
* Refactor bfs method in `hash_bfs.rb`:
|
26
|
+
+ Rename `include_nodes` variable to `visit_internal`
|
27
|
+
+ Update test cases in `hash_bfs_test.rb` to use new method signature
|
28
|
+
+ Update method signature and docstring to reflect new behavior
|
29
|
+
* Update hash conversion logic:
|
30
|
+
+ Rename method parameter from `v` to `object`
|
31
|
+
+ Use `object` instead of `v` consistently throughout the method
|
32
|
+
+ Add documentation for new method name and behavior
|
33
|
+
|
34
|
+
## 2024-10-10 v1.35.0
|
35
|
+
|
36
|
+
### New Features
|
37
|
+
* Implemented breadth-first search in hashes using the `Tins::HashBFS` module.
|
38
|
+
+ Added tests for the `Tins::HashBFS` module.
|
39
|
+
|
40
|
+
### Refactoring and Cleanup
|
41
|
+
* Reformatted code.
|
42
|
+
* Removed TODO note from the `TODO` file.
|
43
|
+
* Cleaned up test requirements:
|
44
|
+
- Added `require 'tins'` to `tests/test_helper.rb`.
|
45
|
+
- Removed unnecessary `require 'tins'` lines from test files.
|
46
|
+
* Refactored BASE16 constants and alphabet:
|
47
|
+
+ Added `BASE16_LOWERCASE_ALPHABET` constant.
|
48
|
+
+ Added `BASE16_UPPERCASE_ALPHABET` constant.
|
49
|
+
|
50
|
+
### Tool Updates
|
51
|
+
* Updated bundler command to use full index:
|
52
|
+
- Added `--full-index` flag to `bundle install`.
|
53
|
+
- Replaced `bundle update` with `bundle install --full-index`.
|
54
|
+
|
55
|
+
## 2024-09-30 v1.34.0
|
56
|
+
|
57
|
+
* **Secure write functionality updated**
|
58
|
+
+ Added support for `Pathname` objects in `secure_write`
|
59
|
+
+ Updated `File.new` call to use `to_s` method on filename
|
60
|
+
+ New test case added for `secure_write` with `Pathname` object
|
61
|
+
* **Refactor version comparisons in various modules**
|
62
|
+
+ Added `Tins::StringVersion.compare` method to compare Ruby versions with operators.
|
63
|
+
+ Replaced direct version comparisons with `compare` method in multiple modules.
|
64
|
+
* **Deprecate deep_const_get and const_defined_in? methods**
|
65
|
+
+ Add deprecation notice for `const_defined_in?` for ruby >= 1.8
|
66
|
+
+ Add deprecation notice for `deep_const_get` method with a new method name `const_get` for ruby >= 2.0
|
67
|
+
* **Refactor deprecation logic and tests**
|
68
|
+
+ Update `Tins::Deprecate#deprecate` method to allow for optional `new_method` parameter.
|
69
|
+
+ Modify `tests/deprecate_test.rb` to test deprecated methods with and without messages.
|
70
|
+
* **Prepare count_by method for deprecation**
|
71
|
+
+ Suggest using `count` with block instead in newer Rubies
|
72
|
+
* **Prepare uniq_by / uniq_by! method for deprecation**
|
73
|
+
+ Suggest using `uniq` / `uniq!` with block instead in newer Rubies
|
74
|
+
|
75
|
+
## 2024-04-17 v1.33.0
|
76
|
+
|
77
|
+
* **Changes for Ruby 3.3 and 3.4**
|
78
|
+
+ Added support for Ruby **3.3**
|
79
|
+
+ Added dependency on `bigdecimal` for upcoming Ruby **3.4**
|
80
|
+
* **Other Changes**
|
81
|
+
+ Halting once is enough
|
82
|
+
+ Added ruby **3.2**, removed some older ones
|
83
|
+
+ Added test process convenience method
|
84
|
+
|
85
|
+
## 2022-11-21 v1.32.1
|
86
|
+
|
87
|
+
* Removed mutex for finalizer, allowing Ruby to handle cleanup instead.
|
88
|
+
* Significant changes:
|
89
|
+
+ Removed `mutex` variable
|
90
|
+
+ Updated code to rely on Ruby's built-in finalization mechanism
|
91
|
+
|
92
|
+
## 2022-11-17 v1.32.0
|
93
|
+
|
94
|
+
* **attempt** method now supports passing of previously caught exception into
|
95
|
+
the called block to let the handling behaviour depend on it.
|
96
|
+
* Some smaller changes to make debugging on multiple Ruby releases, easier via
|
97
|
+
all_images.
|
98
|
+
* Enable fast failing mode
|
99
|
+
* Add convenience method to create `Tins::StringVersion` objects.
|
100
|
+
* Pass previous exception to attempt block ...
|
101
|
+
... to allow reacting to it, logging it etc.
|
102
|
+
* Remove additional groups
|
103
|
+
* Use debug instead of byebug for development
|
104
|
+
* Ignore more hidden files in the package
|
105
|
+
* Update Ruby version to **3.1**
|
data/Rakefile
CHANGED
@@ -14,18 +14,17 @@ GemHadar do
|
|
14
14
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.rvmrc', 'coverage', '.rbx',
|
15
15
|
'.AppleDouble', '.DS_Store', 'tags', '.bundle', '.byebug_history'
|
16
16
|
package_ignore '.all_images.yml', '.tool-versions', '.gitignore', 'VERSION',
|
17
|
-
|
18
|
-
*Dir.glob('.github/**/*', File::FNM_DOTMATCH)
|
17
|
+
'.utilsrc', 'TODO', *Dir.glob('.github/**/*', File::FNM_DOTMATCH)
|
19
18
|
|
20
19
|
readme 'README.md'
|
21
20
|
licenses << 'MIT'
|
22
21
|
|
23
22
|
required_ruby_version '>= 2.0'
|
24
|
-
development_dependency 'utils'
|
25
23
|
development_dependency 'all_images'
|
26
24
|
development_dependency 'debug'
|
27
25
|
development_dependency 'term-ansicolor'
|
28
26
|
development_dependency 'test-unit', '~>3.1'
|
29
27
|
development_dependency 'simplecov'
|
30
28
|
dependency 'sync'
|
29
|
+
dependency 'bigdecimal'
|
31
30
|
end
|
data/lib/tins/concern.rb
CHANGED
@@ -19,12 +19,48 @@ module Tins
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
def prepend_features(base)
|
23
|
+
if base.instance_variable_defined?("@_dependencies")
|
24
|
+
base.instance_variable_get("@_dependencies") << self
|
25
|
+
false
|
26
|
+
else
|
27
|
+
return false if base < self
|
28
|
+
@_dependencies.each { |dep| base.send(:include, dep) }
|
29
|
+
super
|
30
|
+
base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
|
31
|
+
base.class_eval(&@_prepended_block) if instance_variable_defined?("@_prepended_block")
|
32
|
+
Thread.current[:tin_concern_args] = nil
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
22
37
|
def included(base = nil, &block)
|
23
38
|
if base.nil?
|
39
|
+
instance_variable_defined?(:@_included_block) and
|
40
|
+
raise StandardError, "included block already defined"
|
24
41
|
@_included_block = block
|
25
42
|
else
|
26
43
|
super
|
27
44
|
end
|
28
45
|
end
|
46
|
+
|
47
|
+
def prepended(base = nil, &block)
|
48
|
+
if base.nil?
|
49
|
+
instance_variable_defined?(:@_prepended_block) and
|
50
|
+
raise StandardError, "prepended block already defined"
|
51
|
+
@_prepended_block = block
|
52
|
+
else
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def class_methods(&block)
|
58
|
+
modul = const_get(:ClassMethods) if const_defined?(:ClassMethods, false)
|
59
|
+
unless modul
|
60
|
+
modul = Module.new
|
61
|
+
const_set(:ClassMethods, modul)
|
62
|
+
end
|
63
|
+
modul.module_eval(&block)
|
64
|
+
end
|
29
65
|
end
|
30
66
|
end
|
data/lib/tins/count_by.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
+
require 'tins/string_version'
|
2
|
+
|
1
3
|
module Tins
|
2
4
|
module CountBy
|
3
|
-
|
4
|
-
|
5
|
-
|
5
|
+
if Tins::StringVersion.compare(RUBY_VERSION, :<=, "1.8")
|
6
|
+
def count_by(&block)
|
7
|
+
block ||= lambda { |x| true }
|
8
|
+
inject(0) { |s, e| s += 1 if block.call(e); s }
|
9
|
+
end
|
10
|
+
else
|
11
|
+
require 'tins/deprecate'
|
12
|
+
extend Tins::Deprecate
|
13
|
+
|
14
|
+
deprecate method:
|
15
|
+
def count_by(&block)
|
16
|
+
count(&block)
|
17
|
+
end,
|
18
|
+
new_method: :count
|
6
19
|
end
|
7
20
|
end
|
8
21
|
end
|
data/lib/tins/deep_const_get.rb
CHANGED
@@ -1,45 +1,59 @@
|
|
1
|
+
require 'tins/string_version'
|
2
|
+
|
1
3
|
module Tins
|
2
4
|
module DeepConstGet
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
class << self
|
6
|
+
if ::Object.method(:const_defined?).arity == 1
|
7
|
+
# :nocov:
|
8
|
+
# We do not create coverage on 1.8
|
9
|
+
def const_defined_in?(modul, constant)
|
10
|
+
modul.const_defined?(constant)
|
11
|
+
end
|
12
|
+
# :nocov:
|
13
|
+
else
|
14
|
+
require 'tins/deprecate'
|
15
|
+
extend Tins::Deprecate
|
16
|
+
|
17
|
+
deprecate method:
|
18
|
+
def const_defined_in?(modul, constant)
|
19
|
+
modul.const_defined?(constant, false)
|
20
|
+
end,
|
21
|
+
new_method: :const_defined?
|
13
22
|
end
|
14
|
-
end
|
15
23
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
if Tins::StringVersion.compare(RUBY_VERSION, :<, '2.0')
|
25
|
+
def deep_const_get(path, start_module = Object)
|
26
|
+
path.to_s.split('::').inject(start_module) do |p, c|
|
27
|
+
case
|
28
|
+
when c.empty?
|
29
|
+
if start_module == Object
|
30
|
+
Object
|
31
|
+
else
|
32
|
+
raise ArgumentError, "top level constants cannot be reached from"\
|
33
|
+
" start module #{start_module.inspect}"
|
34
|
+
end
|
35
|
+
when const_defined_in?(p, c)
|
36
|
+
p.const_get(c)
|
23
37
|
else
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
else
|
30
|
-
begin
|
31
|
-
p.const_missing(c)
|
32
|
-
rescue NameError => e
|
33
|
-
raise ArgumentError, "can't get const #{path}: #{e}"
|
38
|
+
begin
|
39
|
+
p.const_missing(c)
|
40
|
+
rescue NameError => e
|
41
|
+
raise ArgumentError, "can't get const #{path}: #{e}"
|
42
|
+
end
|
34
43
|
end
|
35
44
|
end
|
36
45
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
else
|
47
|
+
require 'tins/deprecate'
|
48
|
+
extend Tins::Deprecate
|
49
|
+
|
50
|
+
deprecate method:
|
51
|
+
def deep_const_get(path, start_module = Object)
|
52
|
+
start_module.const_get(path)
|
53
|
+
rescue NameError => e
|
54
|
+
raise ArgumentError, "can't get const #{path}: #{e}"
|
55
|
+
end,
|
56
|
+
new_method: :const_get
|
43
57
|
end
|
44
58
|
end
|
45
59
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Tins
|
2
|
+
module Deprecate
|
3
|
+
def deprecate(method:, new_method: nil, message: nil)
|
4
|
+
message ||= '[DEPRECATION] `%{method}` is deprecated. Please use `%{new_method}` instead.'
|
5
|
+
message = message % { method: method, new_method: new_method }
|
6
|
+
m = Module.new do
|
7
|
+
define_method(method) do |*a, **kw, &b|
|
8
|
+
warn message
|
9
|
+
super(*a, **kw, &b)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
prepend m
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/tins/duration.rb
CHANGED
@@ -2,6 +2,48 @@ module Tins
|
|
2
2
|
class Duration
|
3
3
|
include Comparable
|
4
4
|
|
5
|
+
# Returns the number of seconds represented by the given duration string
|
6
|
+
# according to the provided template format.
|
7
|
+
#
|
8
|
+
# @param [String] string The duration string to parse.
|
9
|
+
# @param [String] template for the duration format, see {#format}.
|
10
|
+
#
|
11
|
+
# @return [Integer, Float] The number of (fractional) seconds of the duration.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# Tins::Duration.parse('6+05:04:03', template: '%S%d+%h:%m:%s') # => 536643
|
15
|
+
# Tins::Duration.parse('6+05:04:03.21', template: '%S%d+%h:%m:%s.%f') # => 536643.21
|
16
|
+
def self.parse(string, template: '%S%d+%h:%m:%s.%f')
|
17
|
+
s, t = string.to_s.dup, template.dup
|
18
|
+
d, sd = 0, 1
|
19
|
+
loop do
|
20
|
+
t.sub!(/\A(%[Sdhmsf%]|.)/) { |directive|
|
21
|
+
case directive
|
22
|
+
when '%S' then s.sub!(/\A-?/) { sd *= -1 if _1 == ?-; '' }
|
23
|
+
when '%d' then s.sub!(/\A\d+/) { d += 86_400 * _1.to_i; '' }
|
24
|
+
when '%h' then s.sub!(/\A\d+/) { d += 3_600 * _1.to_i; '' }
|
25
|
+
when '%m' then s.sub!(/\A\d+/) { d += 60 * _1.to_i; '' }
|
26
|
+
when '%s' then s.sub!(/\A\d+/) { d += _1.to_i; '' }
|
27
|
+
when '%f' then s.sub!(/\A\d+/) { d += Float(?. + _1); '' }
|
28
|
+
when '%%' then
|
29
|
+
if s[0] == ?%
|
30
|
+
s[0] = ''
|
31
|
+
else
|
32
|
+
raise "expected %s, got #{s.inspect}"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
if directive == s[0]
|
36
|
+
s[0] = ''
|
37
|
+
else
|
38
|
+
raise ArgumentError, "expected #{t.inspect}, got #{s.inspect}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
''
|
42
|
+
} or break
|
43
|
+
end
|
44
|
+
sd * d
|
45
|
+
end
|
46
|
+
|
5
47
|
def initialize(seconds)
|
6
48
|
@negative = seconds < 0
|
7
49
|
seconds = seconds.abs
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'tins/thread_local'
|
2
|
+
|
3
|
+
module Tins
|
4
|
+
module HashBFS
|
5
|
+
extend Tins::ThreadLocal
|
6
|
+
|
7
|
+
thread_local :seen
|
8
|
+
|
9
|
+
# The bfs method performs a breadth-first search on the object's structure,
|
10
|
+
# visiting all elements and yielding their indices and values to the block.
|
11
|
+
#
|
12
|
+
# @param visit_internal [ true, false ] whether to visit internal hashes or arrays
|
13
|
+
# @yield [ index, value ] yields each element's index and value to the block
|
14
|
+
#
|
15
|
+
# @raise [ ArgumentError ] if no &block argument was provided
|
16
|
+
#
|
17
|
+
# @example bfs { |index, value| … } # performs a breadth-first search on the object's structure
|
18
|
+
#
|
19
|
+
# @return [ self ] returns the receiver
|
20
|
+
def bfs(visit_internal: false, &block)
|
21
|
+
block or raise ArgumentError, 'require &block argument'
|
22
|
+
self.seen = {}
|
23
|
+
queue = []
|
24
|
+
queue.push([ nil, self ])
|
25
|
+
while (index, object = queue.shift)
|
26
|
+
case
|
27
|
+
when seen[object.__id__]
|
28
|
+
next
|
29
|
+
when Hash === object
|
30
|
+
seen[object.__id__] = true
|
31
|
+
object.each do |k, v|
|
32
|
+
queue.push([ k, convert_to_hash_or_ary(v) ])
|
33
|
+
end
|
34
|
+
visit_internal or next
|
35
|
+
when Array === object
|
36
|
+
seen[object.__id__] = true
|
37
|
+
object.each_with_index do |v, i|
|
38
|
+
queue.push([ i, convert_to_hash_or_ary(v) ])
|
39
|
+
end
|
40
|
+
visit_internal or next
|
41
|
+
end
|
42
|
+
block.(index, object)
|
43
|
+
end
|
44
|
+
self
|
45
|
+
ensure
|
46
|
+
self.seen = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
# Converts the given object into a hash or array if possible
|
50
|
+
#
|
51
|
+
# @param object [Object] The object to convert
|
52
|
+
#
|
53
|
+
# @return [Hash, Array, Object] The converted object or itself if not convertible
|
54
|
+
def convert_to_hash_or_ary(object)
|
55
|
+
case
|
56
|
+
when object.respond_to?(:to_hash)
|
57
|
+
object.to_hash
|
58
|
+
when object.respond_to?(:to_ary)
|
59
|
+
object.to_ary
|
60
|
+
else
|
61
|
+
object
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
require 'tins/alias'
|
data/lib/tins/secure_write.rb
CHANGED
@@ -2,7 +2,7 @@ module Tins
|
|
2
2
|
module SecureWrite
|
3
3
|
# Write to a file atomically
|
4
4
|
def secure_write(filename, content = nil, mode = 'w')
|
5
|
-
temp = File.new(filename + ".tmp.#$$.#{Time.now.to_f}", mode)
|
5
|
+
temp = File.new(filename.to_s + ".tmp.#$$.#{Time.now.to_f}", mode)
|
6
6
|
if content.nil? and block_given?
|
7
7
|
yield temp
|
8
8
|
elsif !content.nil?
|
data/lib/tins/sexy_singleton.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'tins/string_version'
|
1
2
|
require 'singleton'
|
2
3
|
|
3
4
|
module Tins
|
@@ -12,7 +13,7 @@ module Tins
|
|
12
13
|
class << SexySingleton
|
13
14
|
alias __old_singleton_included__ included
|
14
15
|
|
15
|
-
if RUBY_VERSION
|
16
|
+
if Tins::StringVersion.compare(RUBY_VERSION, :<, "2.7")
|
16
17
|
def included(klass)
|
17
18
|
__old_singleton_included__(klass)
|
18
19
|
(class << klass; self; end).class_eval do
|
data/lib/tins/string_version.rb
CHANGED
data/lib/tins/terminal.rb
CHANGED
data/lib/tins/time_dummy.rb
CHANGED
data/lib/tins/timed_cache.rb
CHANGED
data/lib/tins/token.rb
CHANGED
@@ -15,7 +15,11 @@ module Tins
|
|
15
15
|
|
16
16
|
BASE32_EXTENDED_HEX_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUV".freeze
|
17
17
|
|
18
|
-
|
18
|
+
BASE16_UPPERCASE_ALPHABET = "0123456789ABCDEF".freeze
|
19
|
+
|
20
|
+
BASE16_LOWERCASE_ALPHABET = "0123456789abcdef".freeze
|
21
|
+
|
22
|
+
BASE16_ALPHABET = BASE16_UPPERCASE_ALPHABET
|
19
23
|
|
20
24
|
def initialize(bits: 128, length: nil, alphabet: DEFAULT_ALPHABET, random: SecureRandom)
|
21
25
|
alphabet.size > 1 or raise ArgumentError, 'need at least 2 symbols in alphabet'
|
data/lib/tins/uniq_by.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
+
require 'tins/string_version'
|
2
|
+
|
1
3
|
module Tins
|
2
4
|
module UniqBy
|
3
|
-
|
4
|
-
|
5
|
-
|
5
|
+
if Tins::StringVersion.compare(RUBY_VERSION, :<=, "1.8")
|
6
|
+
def uniq_by(&block)
|
7
|
+
block ||= lambda { |x| x }
|
8
|
+
inject({}) { |h, e| h[ block.call(e) ] ||= e; h }.values
|
9
|
+
end
|
10
|
+
else
|
11
|
+
require 'tins/deprecate'
|
12
|
+
extend Tins::Deprecate
|
13
|
+
|
14
|
+
deprecate method:
|
15
|
+
def uniq_by(&block)
|
16
|
+
uniq(&block)
|
17
|
+
end,
|
18
|
+
new_method: :uniq
|
6
19
|
end
|
7
20
|
end
|
8
21
|
end
|
data/lib/tins/version.rb
CHANGED
data/lib/tins/xt/count_by.rb
CHANGED
data/lib/tins/xt/uniq_by.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'tins/string_version'
|
1
2
|
require 'tins/uniq_by'
|
2
3
|
|
3
4
|
module Tins
|
@@ -6,10 +7,19 @@ module Tins
|
|
6
7
|
end
|
7
8
|
|
8
9
|
class ::Array
|
9
|
-
|
10
|
+
if Tins::StringVersion.compare(RUBY_VERSION, :<=, "1.8")
|
11
|
+
include UniqBy
|
12
|
+
|
13
|
+
def uniq_by!(&b)
|
14
|
+
replace uniq_by(&b)
|
15
|
+
end
|
16
|
+
else
|
17
|
+
require 'tins/deprecate'
|
18
|
+
extend Tins::Deprecate
|
10
19
|
|
11
|
-
|
12
|
-
|
20
|
+
deprecate method:
|
21
|
+
alias_method(:uniq_by!, :uniq!),
|
22
|
+
new_method: :uniq!
|
13
23
|
end
|
14
24
|
end
|
15
25
|
end
|
data/lib/tins/xt.rb
CHANGED
data/lib/tins.rb
CHANGED
data/tests/annotate_test.rb
CHANGED