y_support 1.0.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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +2 -0
  7. data/lib/y_support/all.rb +40 -0
  8. data/lib/y_support/core_ext/array/misc.rb +45 -0
  9. data/lib/y_support/core_ext/array.rb +1 -0
  10. data/lib/y_support/core_ext/enumerable/misc.rb +32 -0
  11. data/lib/y_support/core_ext/enumerable.rb +1 -0
  12. data/lib/y_support/core_ext/hash/misc.rb +90 -0
  13. data/lib/y_support/core_ext/hash.rb +1 -0
  14. data/lib/y_support/core_ext/module/misc.rb +43 -0
  15. data/lib/y_support/core_ext/module.rb +2 -0
  16. data/lib/y_support/core_ext/numeric/misc.rb +13 -0
  17. data/lib/y_support/core_ext/numeric.rb +1 -0
  18. data/lib/y_support/core_ext/object/misc.rb +31 -0
  19. data/lib/y_support/core_ext/object.rb +1 -0
  20. data/lib/y_support/core_ext/string/misc.rb +80 -0
  21. data/lib/y_support/core_ext/string.rb +1 -0
  22. data/lib/y_support/core_ext/symbol/misc.rb +19 -0
  23. data/lib/y_support/core_ext/symbol.rb +1 -0
  24. data/lib/y_support/core_ext.rb +5 -0
  25. data/lib/y_support/inert_recorder.rb +51 -0
  26. data/lib/y_support/local_object.rb +39 -0
  27. data/lib/y_support/misc.rb +28 -0
  28. data/lib/y_support/name_magic.rb +373 -0
  29. data/lib/y_support/null_object.rb +96 -0
  30. data/lib/y_support/respond_to.rb +32 -0
  31. data/lib/y_support/stdlib_ext/matrix/misc.rb +134 -0
  32. data/lib/y_support/stdlib_ext/matrix.rb +2 -0
  33. data/lib/y_support/stdlib_ext.rb +3 -0
  34. data/lib/y_support/typing/array/typing.rb +17 -0
  35. data/lib/y_support/typing/array.rb +1 -0
  36. data/lib/y_support/typing/enumerable/typing.rb +75 -0
  37. data/lib/y_support/typing/enumerable.rb +1 -0
  38. data/lib/y_support/typing/hash/typing.rb +76 -0
  39. data/lib/y_support/typing/hash.rb +1 -0
  40. data/lib/y_support/typing/module/typing.rb +42 -0
  41. data/lib/y_support/typing/module.rb +1 -0
  42. data/lib/y_support/typing/object/typing.rb +178 -0
  43. data/lib/y_support/typing/object.rb +1 -0
  44. data/lib/y_support/typing.rb +43 -0
  45. data/lib/y_support/unicode.rb +76 -0
  46. data/lib/y_support/version.rb +3 -0
  47. data/lib/y_support.rb +33 -0
  48. data/test/inert_recorder_test.rb +34 -0
  49. data/test/local_object_test.rb +37 -0
  50. data/test/misc_test/test_module/fixture_class.rb +8 -0
  51. data/test/misc_test.rb +289 -0
  52. data/test/name_magic_test.rb +57 -0
  53. data/test/null_object_test.rb +50 -0
  54. data/test/respond_to_test.rb +46 -0
  55. data/test/typing_test.rb +213 -0
  56. data/test/unicode_test.rb +39 -0
  57. data/y_support.gemspec +22 -0
  58. metadata +137 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 39372bbe12e6643f53e78e2b4fd8666477554a67
4
+ data.tar.gz: 9d1c8f648ab7369104ba1ca178fe6ca4abec4cf7
5
+ SHA512:
6
+ metadata.gz: 7e3457d0f805683af3c83018bb7174b161868f614a77b90e7ecc022937ec9b4768fbbfc904717b97beb71dbe0f96296cac46fe60f52db06f89c80c9afa5ce755
7
+ data.tar.gz: 8a57a47dcb40f4c286ffcdf3ad19c0ccd3cd6a58bb32f7d32861701c6907c4734db0eb6e72b6490afcf43e8c2797b0661fda1e7166ed15267736729d45fb06b8
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *~
2
+ .#*
3
+ \#*#
4
+ *.gem
5
+ *.rbc
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in y_support.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 boris
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # YSupport
2
+
3
+ Common support library for Y* gems.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'y_support'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install y_support
18
+
19
+ ## Usage
20
+
21
+ Require 'y_support/all', or require 'y_support/something', and use it.
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,40 @@
1
+ #encoding: utf-8
2
+
3
+ require 'y_support'
4
+ require 'y_support/name_magic'
5
+ require 'y_support/typing'
6
+ require 'y_support/unicode'
7
+ require 'y_support/respond_to'
8
+ require 'y_support/null_object'
9
+ require 'y_support/inert_recorder'
10
+ require 'y_support/local_object'
11
+ require 'y_support/misc'
12
+
13
+
14
+ # # Test me!
15
+ # class BlankSlate
16
+ # class << self
17
+ # # Hide the method named +name+ in the BlankSlate class. Don't
18
+ # # hide +instance_eval+ or any method beginning with "__".
19
+ # def hide( name )
20
+ # if instance_methods.include? name and
21
+ # name !~ /^(__|instance_eval)/
22
+ # @hidden_methods ||= {}
23
+ # @hidden_methods[name] = instance_method name
24
+ # undef_method name
25
+ # end
26
+ # end
27
+
28
+ # def find_hidden_method name
29
+ # @hidden_methods ||= {}
30
+ # @hidden_methods[name] || superclass.find_hidden_method( name )
31
+ # end
32
+
33
+ # # Redefine a previously hidden method
34
+ # def reveal name
35
+ # unbound_method = find_hidden_method name
36
+ # fail "Don't know how to reveal method '#{name}'" unless unbound_method
37
+ # define_method( name, unbound_method )
38
+ # end
39
+ # end
40
+ # end # class BlankSlate
@@ -0,0 +1,45 @@
1
+ class Array
2
+ # Converts an array, whose elements are also arrays, to a hash. Head
3
+ # (position 0) of each array is made to point at the rest of the array
4
+ # (tail), normally starting immediately after the head (position 1). The
5
+ # starting position of the tail can be controlled by an optional
6
+ # argument. Tails of 2 and more elements are represented as arrays.
7
+ #
8
+ def to_hash( tail_from = 1 )
9
+ self.reject { | e | e[0].nil? }.reduce({}) { |a, e|
10
+ tail = e[tail_from..-1]
11
+ a.merge( { e[0] => tail.size >= 2 ? tail : tail[0] } )
12
+ }
13
+ end
14
+
15
+ # Does things for each consecutive pair (expects a binary block).
16
+ #
17
+ def each_consecutive_pair
18
+ if block_given?
19
+ return self if ( n = self.size - 1 ) <= 0
20
+ n.times.with_index{|i| yield( self[i], self[i+1] ) }
21
+ return self
22
+ else
23
+ return Enumerator.new do |yielder|
24
+ n.times.with_index{|i| yielder << [ self[i], self[i+1] ] } unless
25
+ ( n = self.size - 1 ) <= 0
26
+ end
27
+ end
28
+ end
29
+
30
+ # Allows style &[ function, *arguments ]
31
+ #
32
+ def to_proc
33
+ proc { |receiver| receiver.send *self }
34
+ end # def to_proc
35
+
36
+ # TEST ME
37
+ # def pretty_inspect
38
+ # each_slice( 4 ) { |slice|
39
+ # slice.map { |e|
40
+ # str = e.to_s[0..25]
41
+ # str + ' ' * ( 30 - str.size )
42
+ # }.reduce( :+ ) + "\n"
43
+ # }.reduce( :+ )
44
+ # end
45
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/array/misc'
@@ -0,0 +1,32 @@
1
+ #encoding: utf-8
2
+
3
+ module Enumerable
4
+ # Checks whether #all? collection elements are #kind_of? module
5
+ # supplied as an argument
6
+ #
7
+ def all_kind_of?( kind )
8
+ all? {|e| e.kind_of? kind }
9
+ end
10
+
11
+ # Checks whether #all? collection elements are #kind_of? Numeric.
12
+ #
13
+ def all_numeric?
14
+ all? {|e| e.kind_of? Numeric }
15
+ end
16
+
17
+ # Checks whether the receiver collection is fully included in the
18
+ # collection supplied as an argument.
19
+ #
20
+ def subset_of?( other_collection )
21
+ all? {|e| other_collection.include? e }
22
+ end
23
+ alias :⊂? :subset_of?
24
+
25
+ # Checks whether the receiver collection contains every element of
26
+ # the collection supplied as an argument.
27
+ #
28
+ def superset_of?( other_collection )
29
+ other.all? {|e| self.include? e }
30
+ end
31
+ alias :⊃? :superset_of?
32
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/enumerable/misc'
@@ -0,0 +1,90 @@
1
+ #encoding: utf-8
2
+
3
+ require 'active_support/core_ext/hash/reverse_merge'
4
+
5
+ class Hash
6
+ # reversed merge!: defaults.merge( self! )
7
+ alias :default! :reverse_merge!
8
+
9
+ # Applies a block as a mapping on all keys, returning a new hash
10
+ def with_keys
11
+ keys.each_with_object self.class.new do |hash_key, ꜧ|
12
+ ꜧ[ yield( hash_key ) ] = self[ hash_key ]
13
+ end
14
+ end
15
+ alias :do_with_keys :with_keys
16
+
17
+ # The difference from do_with_keys is that modify_keys expects block
18
+ # that takes 2 arguments (key: value pair) and returns the new key.
19
+ def modify_keys
20
+ each_with_object self.class.new do |hash_pair, ꜧ|
21
+ ꜧ[ yield( hash_pair ) ] = self[ hash_pair[0] ]
22
+ end
23
+ end
24
+
25
+ # Applies a block as a mapping on all values, returning a new hash
26
+ def with_values
27
+ each_with_object self.class.new do |hash_pair, ꜧ|
28
+ ꜧ[ hash_pair[0] ] = yield( hash_pair[1] )
29
+ end
30
+ end
31
+ alias :do_with_values :with_values
32
+
33
+ # Like #do_with_values, but modifies the receiver.
34
+ def with_values!
35
+ each_with_object self do |hash_pair, ꜧ|
36
+ hash_key, hash_val = hash_pair
37
+ ꜧ[ hash_key ] = yield( hash_val )
38
+ end
39
+ end
40
+ alias :do_with_values! :with_values!
41
+
42
+ # The difference from #do_with_values is that modify_values expects block
43
+ # that takes 2 arguments (key: value pair) and returns the new value.
44
+ def modify_values
45
+ each_with_object self.class.new do |hash_pair, ꜧ|
46
+ ꜧ[ hash_pair[0] ] = yield( hash_pair )
47
+ end
48
+ end
49
+
50
+ # Like #modify_values, but modifies the receiver
51
+ def modify_values!
52
+ each_with_object self do |hash_pair, ꜧ|
53
+ ꜧ[ hash_pair[0] ] = yield( hash_pair )
54
+ end
55
+ end
56
+
57
+ # Like #map that returns a hash.
58
+ def modify
59
+ each_with_object self.class.new do |hash_pair, ꜧ|
60
+ key, val = yield hash_pair
61
+ ꜧ[key] = val
62
+ end
63
+ end
64
+
65
+ # Makes hash keys accessible as methods. If the hash keys collide with
66
+ # its methods, ArgumentError is raised, unless :overwrite_methods
67
+ # option == true.
68
+ #
69
+ def dot!( oo = {} )
70
+ keys.each do |key|
71
+ msg = "key #{key} of #dot!-ted hash is not convertible to a symbol"
72
+ raise ArgumentError, msg unless key.respond_to? :to_sym
73
+ unless oo[:overwrite_methods]
74
+ if methods.include? key.to_sym
75
+ raise ArgumentError, "#dot!-ted hash must not have key names " +
76
+ "colliding with its methods"
77
+ end
78
+ end
79
+
80
+ define_singleton_method key.to_sym do
81
+ self[key]
82
+ end
83
+
84
+ define_singleton_method "#{key}=".to_sym do |value|
85
+ self[key] = value
86
+ end
87
+ end
88
+ return self
89
+ end
90
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/hash/misc'
@@ -0,0 +1,43 @@
1
+ #encoding: utf-8
2
+
3
+ class Module
4
+ # Further automation of soon-to-be-deprecated #autorequire.
5
+ #
6
+ def autoreq( *symbols, descending_path: '..', ascending_path_prefix: 'lib' )
7
+
8
+ require 'active_support/core_ext/string/inflections'
9
+
10
+ namespace = self.name
11
+ namespace_path = namespace.underscore
12
+ namespace_chain = namespace.split "::"
13
+ ascending_path = ascending_path_prefix + '/' + namespace_path
14
+ symbols.map( &:to_s ).each { |ς|
15
+ next if ς.strip.empty?
16
+ camelized_ß = ς.camelize.to_sym
17
+ path = './' + [ descending_path, ascending_path, ς ].join( '/' )
18
+ autoload camelized_ß, path
19
+ }
20
+ end
21
+
22
+ # I didn't write this method by myself.
23
+ #
24
+ def attr_accessor_with_default *symbols, &block
25
+ raise ArgumentError, 'Block with default value required!' unless block
26
+ symbols.each { |ß|
27
+ module_eval {
28
+ define_method "#{ß}=" do |arg|
29
+ instance_variable_set "@#{ß}", arg
30
+ end
31
+ define_method ß do
32
+ singleton_class.class_eval { attr_reader ß }
33
+ if instance_variables.include? "@#{ß}".to_sym then
34
+ instance_variable_get "@#{ß}"
35
+ else
36
+ instance_variable_set "@#{ß}", block.call
37
+ end
38
+ end
39
+ }
40
+ }
41
+ end
42
+ alias :attr_accessor_w_default :attr_accessor_with_default
43
+ end
@@ -0,0 +1,2 @@
1
+ require 'y_support'
2
+ require 'y_support/core_ext/module/misc'
@@ -0,0 +1,13 @@
1
+ #encoding: utf-8
2
+
3
+ class << Integer
4
+ def zero; 0 end
5
+ end
6
+
7
+ class << Float
8
+ def zero; 0.0 end
9
+ end
10
+
11
+ class << Complex
12
+ def zero; Complex 0, 0 end
13
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/numeric/misc'
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Object
4
+ def const_set_if_not_defined( const, value )
5
+ mod = self.is_a?(Module) ? self : self.singleton_class
6
+ mod.const_set( const, value ) unless mod.const_defined?( const )
7
+ end
8
+
9
+ def const_redefine_without_warning( const, value )
10
+ mod = self.is_a?(Module) ? self : self.singleton_class
11
+ mod.send(:remove_const, const) if mod.const_defined?( const )
12
+ mod.const_set( const, value )
13
+ end
14
+
15
+ # Create public attributes (ie. with readers) and initialize them with
16
+ # prescribed values. Takes a hash of { symbol => value } pairs. Existing methods
17
+ # are not overwritten by the new getters, unless option :overwrite_methods
18
+ # is set to true.
19
+ def singleton_set_attr_with_readers( hash, oo = {} )
20
+ hash.each { |key, val|
21
+ key = key.aE_respond_to( :to_sym, "key of the attr hash" ).to_sym
22
+ instance_variable_set( "@#{key}", val )
23
+ if oo[:overwrite_methods] then ⓒ.module_exec { attr_reader key }
24
+ elsif methods.include? key
25
+ raise "Attempt to add \##{key} getter failed: " +
26
+ "method \##{key} already defined."
27
+ else ⓒ.module_exec { attr_reader key } end
28
+ }
29
+ end
30
+ alias :ⓒ_set_attr_w_readers :singleton_set_attr_with_readers
31
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/object/misc'
@@ -0,0 +1,80 @@
1
+ #encoding: utf-8
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+
5
+ class String
6
+ # Integer() style conversion, or false if conversion impossible.
7
+ #
8
+ def to_Integer
9
+ begin
10
+ int = Integer stripn
11
+ return int
12
+ rescue ArgumentError
13
+ return false
14
+ end
15
+ end
16
+
17
+ # Float() style conversion, or false if conversion impossible.
18
+ #
19
+ def to_Float
20
+ begin
21
+ fl = Float stripn
22
+ return fl
23
+ rescue ArgumentError
24
+ return false
25
+ end
26
+ end
27
+
28
+ # Like #strip, but also strips newlines.
29
+ #
30
+ def stripn
31
+ encode( universal_newline: true )
32
+ .gsub("\n", "")
33
+ .strip
34
+ end
35
+
36
+ # Joins a paragraph of possibly indented, newline separated lines into a
37
+ # single contiguous string.
38
+ #
39
+ def wring_heredoc
40
+ encode(universal_newline: true)
41
+ .split("\n") # split into lines
42
+ .map( &:strip ) # strip them
43
+ .delete_if( &:blank? ) # delete blank lines
44
+ .join " " # and join with whitspace
45
+ end
46
+
47
+ # If the string is empty, it gets replace with the string given as argument.
48
+ #
49
+ def default! default_string
50
+ strip.empty? ? clear << default_string.to_s : self
51
+ end
52
+
53
+ # As it says – replaces spaces with underscores.
54
+ #
55
+ def underscore_spaces
56
+ gsub ' ', '_'
57
+ end
58
+
59
+ # Converts a string into a standard symbol. While Symbol class objects can
60
+ # be created from any string, it is good practice to keep symbols free of
61
+ # whitespaces and weird characters, so that the are typed easily, usable as
62
+ # variable names etc. This method thus removes punctuation, removes
63
+ # superfluous spaces, and underscores the remaining ones, before returning
64
+ # the string.
65
+ #
66
+ def standardize
67
+ ς = self.dup
68
+ ",.;".each_char { |c| ς.gsub! c, " " }
69
+ ς.stripn
70
+ .squeeze(" ")
71
+ .underscore_spaces
72
+ end
73
+
74
+ # Applies #standardize to the receiver and converts the result to a symbol.
75
+ #
76
+ def to_standardized_sym
77
+ standardize
78
+ .to_sym
79
+ end
80
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/string/misc'
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+ class Symbol
3
+ # This method applies String#default! method to the receiver converted to
4
+ # a string. Of course, symbols are immutable, so in spite of the exclamation
5
+ # mark in the method name, a new symbol (supplied as argument) is returned,
6
+ # if the original one is considered "defaulted" (otherwise, original symbol
7
+ # is returned unchanged).
8
+ #
9
+ def default! default_symbol
10
+ to_s.default!( default_symbol ).to_sym
11
+ end
12
+
13
+ # Applies String#to_standardized_sym method to the recevier converted to a
14
+ # string.
15
+ #
16
+ def to_standardized_sym
17
+ to_s.to_standardized_sym
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ require 'y_support/core_ext/symbol/misc'
@@ -0,0 +1,5 @@
1
+ #encoding: utf-8
2
+
3
+ Dir["#{File.dirname( __FILE__ )}/core_ext/*.rb"].sort.each do |path|
4
+ require "y_support/core_ext/#{File.basename( path, '.rb' )}"
5
+ end
@@ -0,0 +1,51 @@
1
+ #encoding: utf-8
2
+
3
+ require 'y_support'
4
+
5
+ # Inert recorder is similar to a null object in the sense, that in response to
6
+ # almost all messages it returns self. But in addition, it records received
7
+ # messages along with their arguments and blocks (if given). Recoded messages
8
+ # are available via #recorded_messages reader, aliased #ρ (small Greek rho).
9
+ # Inert recorder does not require any arguments for initalization, but if they
10
+ # are supplied, they are silently recoded into @init_args (for arguments) and
11
+ # @init_block (for block, if given) instance variables, exposed via standard
12
+ # readers.
13
+ #
14
+ class InertRecorder
15
+ attr_reader :init_args, :init_block, :recorded_messages
16
+ alias ρ recorded_messages
17
+
18
+ # No arguments are required for initialization, but if they are supplied, they
19
+ # are silently recorded into @init_args (for argument array) and @init_block
20
+ # (for block, if given) instance variables, exposed via standard readers.
21
+ #
22
+ def initialize *args, &block
23
+ @init_args = args
24
+ @init_block = block
25
+ @recorded_messages = []
26
+ end
27
+
28
+ # Always true.
29
+ #
30
+ def present?; true end
31
+
32
+ # Always false.
33
+ #
34
+ def blank?; false end
35
+
36
+ # Always true.
37
+ #
38
+ def respond_to? ß, *args, &block; true end
39
+
40
+ def method_missing ß, *args, &block # :nodoc:
41
+ @recorded_messages << [ ß, args, block ]
42
+ return self
43
+ end
44
+ end # class InertRecorder
45
+
46
+
47
+ class Object
48
+ # InertRecorder constructor.
49
+ #
50
+ def InertRecorder *args, &block; InertRecorder.new *args, &block end
51
+ end
@@ -0,0 +1,39 @@
1
+ #encoding: utf-8
2
+
3
+ require 'y_support'
4
+
5
+ # Object, whose business is to stay local to methods. Optional signature
6
+ # provides additional level of safety in ensuring object locality. (Signature
7
+ # accessor is :signature, aliased as :σ (small Greek sigma).)
8
+ #
9
+ class LocalObject
10
+ attr_reader :signature
11
+ alias σ signature
12
+
13
+ # Optional argument signature provides additional level of safety in
14
+ # ascertaining that the object indeed is of local origin.
15
+ #
16
+ def initialize signature=__callee__
17
+ @signature=signature
18
+ end
19
+
20
+ # True if the (optional) signature matches.
21
+ #
22
+ def local_object? signature=__callee__
23
+ signature == self.signature
24
+ end
25
+ alias ℓ? local_object?
26
+ end
27
+
28
+
29
+ class Object
30
+ # LocalObject constructor.
31
+ #
32
+ def LocalObject signature=nil; LocalObject.new signature end
33
+ alias L! LocalObject
34
+
35
+ # False for normal objects, overriden in the LocalObject class.
36
+ #
37
+ def local_object? signature=nil; false end
38
+ alias ℓ? local_object?
39
+ end
@@ -0,0 +1,28 @@
1
+ #encoding: utf-8
2
+ require 'y_support'
3
+
4
+ # Typing library.
5
+ #
6
+ # Apart from usual <em>typing by class and ancestry</em>, supported by built-in
7
+ # #kind_of?, alias #is_a? inquirerers, this typing library provides support for
8
+ # provides support for <em>typing by declaration</em> and <em>duck typing</em>.
9
+ #
10
+ # 1. Using method <b>declare_compliance</b>, a module can explicitly declare that
11
+ # it provides the interface compliant with another module. Corresponding inquirer
12
+ # methods are <b>declared_compliance</b> (returning a list of modules with which
13
+ # the receiver declares compliance or implicitly complies) and
14
+ # <b>declares_compliance?( other_module )</b>, which anwers whether the receiver
15
+ # complies with other_module. An object always implicitly complies with its class
16
+ # and class ancestry.
17
+ #
18
+ # 2. Duck type enforcement for method parameters is supported by a collection of
19
+ # enforcer methods (aka. run-time assertions). These methods look very much like
20
+ # assertions, but they start with <b>tE_...</b>, meaning "enforce by raising
21
+ # TypeError".
22
+
23
+ [ :core_ext, :stdlib_ext ].each do |ext|
24
+ Dir["#{File.dirname( __FILE__ )}/#{ext}/*/misc.rb"].sort.each { |path|
25
+ dir = File.dirname( path ).match( "y_support/#{ext}" ).post_match
26
+ require "y_support/#{ext}#{dir}/misc"
27
+ }
28
+ end