tins 1.43.0 → 1.44.1

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +21 -0
  3. data/README.md +158 -6
  4. data/Rakefile +19 -16
  5. data/examples/let.rb +8 -40
  6. data/examples/mail.rb +0 -1
  7. data/examples/turing.rb +3 -1
  8. data/lib/tins/alias.rb +1 -0
  9. data/lib/tins/annotate.rb +37 -27
  10. data/lib/tins/ask_and_send.rb +41 -0
  11. data/lib/tins/attempt.rb +39 -0
  12. data/lib/tins/bijection.rb +34 -0
  13. data/lib/tins/case_predicate.rb +21 -0
  14. data/lib/tins/complete.rb +16 -0
  15. data/lib/tins/concern.rb +64 -0
  16. data/lib/tins/date_dummy.rb +36 -4
  17. data/lib/tins/date_time_dummy.rb +34 -2
  18. data/lib/tins/deep_dup.rb +9 -2
  19. data/lib/tins/deprecate.rb +12 -0
  20. data/lib/tins/dslkit.rb +559 -83
  21. data/lib/tins/duration.rb +120 -5
  22. data/lib/tins/expose.rb +54 -5
  23. data/lib/tins/extract_last_argument_options.rb +9 -0
  24. data/lib/tins/file_binary.rb +104 -21
  25. data/lib/tins/find.rb +114 -11
  26. data/lib/tins/generator.rb +10 -2
  27. data/lib/tins/go.rb +81 -4
  28. data/lib/tins/hash_bfs.rb +4 -2
  29. data/lib/tins/hash_symbolize_keys_recursive.rb +62 -4
  30. data/lib/tins/hash_union.rb +47 -2
  31. data/lib/tins/if_predicate.rb +31 -0
  32. data/lib/tins/implement.rb +50 -0
  33. data/lib/tins/limited.rb +54 -5
  34. data/lib/tins/lines_file.rb +81 -2
  35. data/lib/tins/lru_cache.rb +54 -17
  36. data/lib/tins/memoize.rb +86 -58
  37. data/lib/tins/method_description.rb +87 -4
  38. data/lib/tins/minimize.rb +39 -11
  39. data/lib/tins/module_group.rb +27 -2
  40. data/lib/tins/named_set.rb +20 -0
  41. data/lib/tins/null.rb +86 -15
  42. data/lib/tins/once.rb +61 -4
  43. data/lib/tins/p.rb +44 -8
  44. data/lib/tins/partial_application.rb +66 -7
  45. data/lib/tins/proc_compose.rb +58 -1
  46. data/lib/tins/proc_prelude.rb +97 -10
  47. data/lib/tins/range_plus.rb +30 -2
  48. data/lib/tins/require_maybe.rb +36 -0
  49. data/lib/tins/responding.rb +39 -0
  50. data/lib/tins/secure_write.rb +24 -4
  51. data/lib/tins/sexy_singleton.rb +45 -48
  52. data/lib/tins/string_byte_order_mark.rb +33 -2
  53. data/lib/tins/string_camelize.rb +31 -2
  54. data/lib/tins/string_underscore.rb +33 -2
  55. data/lib/tins/string_version.rb +179 -10
  56. data/lib/tins/subhash.rb +35 -10
  57. data/lib/tins/temp_io.rb +7 -0
  58. data/lib/tins/temp_io_enum.rb +19 -0
  59. data/lib/tins/terminal.rb +31 -9
  60. data/lib/tins/thread_local.rb +67 -5
  61. data/lib/tins/time_dummy.rb +46 -21
  62. data/lib/tins/to.rb +15 -0
  63. data/lib/tins/to_proc.rb +17 -4
  64. data/lib/tins/token.rb +56 -1
  65. data/lib/tins/unit.rb +288 -149
  66. data/lib/tins/version.rb +1 -1
  67. data/lib/tins/write.rb +14 -3
  68. data/lib/tins/xt/blank.rb +81 -2
  69. data/lib/tins/xt/concern.rb +51 -0
  70. data/lib/tins/xt/full.rb +56 -11
  71. data/lib/tins/xt/irb.rb +46 -2
  72. data/lib/tins/xt/method_description.rb +0 -12
  73. data/lib/tins/xt/minimize.rb +7 -0
  74. data/lib/tins/xt/named.rb +71 -16
  75. data/lib/tins/xt/proc_compose.rb +4 -0
  76. data/lib/tins/xt/subhash.rb +11 -0
  77. data/lib/tins/xt/time_freezer.rb +43 -6
  78. data/lib/tins/xt.rb +1 -3
  79. data/lib/tins.rb +16 -3
  80. data/tests/duration_test.rb +4 -0
  81. data/tests/from_module_test.rb +30 -2
  82. data/tests/implement_test.rb +6 -8
  83. data/tests/lines_file_test.rb +2 -0
  84. data/tests/lru_cache_test.rb +12 -0
  85. data/tests/method_description_test.rb +14 -20
  86. data/tests/partial_application_test.rb +4 -0
  87. data/tests/proc_prelude_test.rb +1 -1
  88. data/tests/scope_test.rb +1 -1
  89. data/tests/string_version_test.rb +2 -0
  90. data/tests/test_helper.rb +5 -2
  91. data/tests/to_test.rb +6 -6
  92. data/tins.gemspec +9 -9
  93. metadata +23 -46
  94. data/.contexts/code_comment.rb +0 -26
  95. data/.contexts/full.rb +0 -31
  96. data/.contexts/lib.rb +0 -26
  97. data/.contexts/yard.md +0 -92
  98. data/.github/workflows/codeql-analysis.yml +0 -72
  99. data/lib/tins/count_by.rb +0 -21
  100. data/lib/tins/deep_const_get.rb +0 -64
  101. data/lib/tins/timed_cache.rb +0 -51
  102. data/lib/tins/uniq_by.rb +0 -23
  103. data/lib/tins/xt/count_by.rb +0 -7
  104. data/lib/tins/xt/deep_const_get.rb +0 -7
  105. data/lib/tins/xt/uniq_by.rb +0 -25
  106. data/tests/count_by_test.rb +0 -17
  107. data/tests/deep_const_get_test.rb +0 -37
  108. data/tests/uniq_by_test.rb +0 -31
  109. /data/{COPYING → LICENSE} +0 -0
data/lib/tins/concern.rb CHANGED
@@ -1,9 +1,49 @@
1
1
  module Tins
2
+ # A module concern implementation that supports dependency tracking, class
3
+ # method inclusion, and block execution hooks.
4
+ #
5
+ # This module provides a way to define reusable module functionality with
6
+ # automatic dependency management, class method injection, and lifecycle
7
+ # callbacks similar to ActiveSupport::Concern but with more control.
8
+ #
9
+ # @example Basic usage
10
+ # module MyConcern
11
+ # extend Tins::Concern
12
+ #
13
+ # included do
14
+ # attr_accessor :logger
15
+ # end
16
+ #
17
+ # def log(message)
18
+ # logger&.info message
19
+ # end
20
+ #
21
+ # class_methods do
22
+ # def my_class_method
23
+ # # ...
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ # class MyClass
29
+ # include MyConcern
30
+ # end
2
31
  module Concern
32
+ # Extends the base object with dependency tracking capabilities.
33
+ #
34
+ # This method initializes an instance variable on the base object to store
35
+ # dependency information.
36
+ #
37
+ # @param base [ Object ] the object being extended
3
38
  def self.extended(base)
4
39
  base.instance_variable_set("@_dependencies", [])
5
40
  end
6
41
 
42
+ # The append_features method includes dependencies and class methods in the
43
+ # base class.
44
+ #
45
+ # @param base [ Object ] the base class to include features in
46
+ # @return [ Boolean ] true if features were appended, false otherwise
7
47
  def append_features(base)
8
48
  if base.instance_variable_defined?("@_dependencies")
9
49
  base.instance_variable_get("@_dependencies") << self
@@ -19,6 +59,14 @@ module Tins
19
59
  end
20
60
  end
21
61
 
62
+ # Prepends the features of this module to the base class.
63
+ #
64
+ # This method handles the inclusion of dependencies and class methods when
65
+ # a module is included in a class. It manages dependency tracking and
66
+ # ensures proper extension of the base class with ClassMethods.
67
+ #
68
+ # @param base [Class] the class that includes this module
69
+ # @return [Boolean] true if the module was successfully prepended, false otherwise
22
70
  def prepend_features(base)
23
71
  if base.instance_variable_defined?("@_dependencies")
24
72
  base.instance_variable_get("@_dependencies") << self
@@ -34,6 +82,11 @@ module Tins
34
82
  end
35
83
  end
36
84
 
85
+ # The included method is called when the module is included in a class or
86
+ # module.
87
+ #
88
+ # @param base [ Object ] the class or module that includes this module
89
+ # @param block [ Proc ] optional block to be executed when included
37
90
  def included(base = nil, &block)
38
91
  if base.nil?
39
92
  instance_variable_defined?(:@_included_block) and
@@ -44,6 +97,11 @@ module Tins
44
97
  end
45
98
  end
46
99
 
100
+ # The prepended method handles the setup of a block for prepend
101
+ # functionality or delegates to the superclass implementation
102
+ #
103
+ # @param base [ Object ] the base object to prepend to, or nil to set up a block
104
+ # @param block [ Proc ] the block to be used for prepend functionality
47
105
  def prepended(base = nil, &block)
48
106
  if base.nil?
49
107
  instance_variable_defined?(:@_prepended_block) and
@@ -54,6 +112,12 @@ module Tins
54
112
  end
55
113
  end
56
114
 
115
+ # Defines a ClassMethods module for the current class and evaluates the
116
+ # given block within it.
117
+ #
118
+ # @param block [Proc] The block to be evaluated in the context of the
119
+ # ClassMethods module
120
+ # @return [Module] The ClassMethods module that was defined or retrieved
57
121
  def class_methods(&block)
58
122
  modul = const_get(:ClassMethods) if const_defined?(:ClassMethods, false)
59
123
  unless modul
@@ -1,13 +1,34 @@
1
1
  require 'date'
2
2
 
3
3
  module Tins
4
+ # A module that provides dummy date functionality for testing purposes.
5
+ #
6
+ # @example Setting a dummy date
7
+ # Date.dummy = Date.parse('2009-09-09')
8
+ #
9
+ # @example Using a dummy date in a block
10
+ # Date.dummy Date.parse('2009-09-09') do
11
+ # # Your code here
12
+ # end
4
13
  module DateDummy
14
+ # The included method is a hook that gets called when this module is
15
+ # included in another class or module.
16
+ #
17
+ # It sets up date freezing functionality by extending the including
18
+ # class/module with special date handling methods. The method modifies the
19
+ # including class/module's singleton class to provide dummy date
20
+ # capabilities.
21
+ #
22
+ # @param modul [Object] the class or module that includes this module
5
23
  def self.included(modul)
6
24
  class << modul
7
25
  alias really_today today
8
26
 
9
27
  remove_method :today rescue nil
10
28
 
29
+ # Sets the dummy date value for date freezing functionality.
30
+ #
31
+ # @param value [Date, String] the date value to set as dummy
11
32
  def dummy=(value)
12
33
  if value.respond_to?(:to_str)
13
34
  value = Date.parse(value.to_str)
@@ -17,6 +38,16 @@ module Tins
17
38
  @dummy = value
18
39
  end
19
40
 
41
+ # The dummy method provides a way to set and temporarily override a
42
+ # dummy value within a block.
43
+ #
44
+ # @param value [Object] the dummy value to set, or nil to get the
45
+ # current dummy value
46
+ # @yield [] yields control to the block if a value is provided
47
+ # @return [Object] the current dummy value if no value parameter was
48
+ # provided
49
+ # @yieldparam value [Object] the dummy value to set within the block
50
+ # @yieldreturn [Object] the result of the block execution
20
51
  def dummy(value = nil)
21
52
  if value.nil?
22
53
  if defined?(@dummy)
@@ -33,6 +64,11 @@ module Tins
33
64
  end
34
65
  end
35
66
 
67
+ # The today method returns the current date. When a dummy date is set,
68
+ # it returns a duplicate of that date. Otherwise, it delegates to the
69
+ # actual today method implementation.
70
+ #
71
+ # @return [Date] the current date or the dummy date if set
36
72
  def today
37
73
  if dummy
38
74
  dummy.dup
@@ -42,12 +78,8 @@ module Tins
42
78
  really_today
43
79
  end
44
80
  end
45
-
46
81
  end
47
82
  super
48
83
  end
49
84
  end
50
85
  end
51
-
52
- require 'tins/alias'
53
-
@@ -1,13 +1,30 @@
1
1
  require 'date'
2
2
 
3
3
  module Tins
4
+ # A module that provides dummy functionality for DateTime class
5
+ #
6
+ # This module allows setting a fixed date and time that will be returned by
7
+ # DateTime.now instead of the actual current time. This is useful for testing
8
+ # purposes where consistent timestamps are required.
4
9
  module DateTimeDummy
10
+ # The included method is a hook that gets called when this module is
11
+ # included in another class or module.
12
+ #
13
+ # It sets up date time freezing functionality by extending the including
14
+ # class/module with special date time handling methods. The method modifies
15
+ # the including class/module's singleton class to provide dummy date time
16
+ # capabilities.
17
+ #
18
+ # @param modul [Object] the class or module that includes this module
5
19
  def self.included(modul)
6
20
  class << modul
7
21
  alias really_now now
8
22
 
9
23
  remove_method :now rescue nil
10
24
 
25
+ # Sets the dummy value for datetime handling.
26
+ #
27
+ # @param value [DateTime, String] the datetime value to set as dummy
11
28
  def dummy=(value)
12
29
  if value.respond_to?(:to_str)
13
30
  value = DateTime.parse(value.to_str)
@@ -17,6 +34,18 @@ module Tins
17
34
  @dummy = value
18
35
  end
19
36
 
37
+ # The dummy method provides a way to set and restore a dummy value
38
+ # within a block.
39
+ #
40
+ # @param value [Object] the dummy value to set, or nil to get the
41
+ # current dummy value
42
+ #
43
+ # @yield [void] yields control to the block if a value is provided
44
+ #
45
+ # @return [Object] the current dummy value if no value parameter is
46
+ # provided
47
+ # @return [Object] the result of the block if a value parameter is
48
+ # provided
20
49
  def dummy(value = nil)
21
50
  if value.nil?
22
51
  if defined?(@dummy)
@@ -33,6 +62,11 @@ module Tins
33
62
  end
34
63
  end
35
64
 
65
+ # The now method returns the current time, using a dummy time if one
66
+ # has been set. If no dummy time is set, it delegates to the actual
67
+ # time retrieval method.
68
+ #
69
+ # @return [Time] the current time or a mocked time if dummy is set
36
70
  def now
37
71
  if dummy
38
72
  dummy.dup
@@ -47,5 +81,3 @@ module Tins
47
81
  end
48
82
  end
49
83
  end
50
-
51
- require 'tins/alias'
data/lib/tins/deep_dup.rb CHANGED
@@ -1,5 +1,14 @@
1
1
  module Tins
2
+ # DeepDup module provides a method to deeply duplicate objects in Ruby.
3
+ #
4
+ # This module extends the Object class with a deep_dup method that creates a
5
+ # recursive copy of an object and all its nested objects.
2
6
  module DeepDup
7
+ # Duplicates an object deeply by marshaling and unmarshaling it. For
8
+ # objects that can't be marshaled, it returns the object itself.
9
+ #
10
+ # @return [Object] a deep duplicate of the object or the object itself if
11
+ # it can't be marshaled
3
12
  def deep_dup
4
13
  Marshal.load(Marshal.dump(self))
5
14
  rescue TypeError
@@ -7,5 +16,3 @@ module Tins
7
16
  end
8
17
  end
9
18
  end
10
-
11
- require 'tins/alias'
@@ -1,5 +1,17 @@
1
1
  module Tins
2
+ # A module for deprecating methods with customizable messages and warnings.
3
+ #
4
+ # @example
5
+ # class MyClass
6
+ # extend Tins::Deprecate
7
+ # deprecate method: :old_method, new_method: :new_method
8
+ # end
2
9
  module Deprecate
10
+ # Deprecates a method and issues a warning when called.
11
+ #
12
+ # @param method [ Symbol ] the name of the method to deprecate
13
+ # @param new_method [ Symbol ] the name of the replacement method
14
+ # @param message [ String ] the warning message to display
3
15
  def deprecate(method:, new_method: nil, message: nil)
4
16
  message ||= '[DEPRECATION] `%{method}` is deprecated. Please use `%{new_method}` instead.'
5
17
  message = message % { method: method, new_method: new_method }