vigilem-support 0.0.9
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 +7 -0
- data/lib/vigilem/ffi.rb +19 -0
- data/lib/vigilem/ffi/array_pointer_sync.rb +382 -0
- data/lib/vigilem/ffi/struct.rb +54 -0
- data/lib/vigilem/ffi/utils.rb +240 -0
- data/lib/vigilem/ffi/utils/struct.rb +93 -0
- data/lib/vigilem/support.rb +31 -0
- data/lib/vigilem/support/core_ext.rb +13 -0
- data/lib/vigilem/support/core_ext/debug_puts.rb +5 -0
- data/lib/vigilem/support/core_ext/enumerable.rb +25 -0
- data/lib/vigilem/support/key_map.rb +323 -0
- data/lib/vigilem/support/key_map_info.rb +85 -0
- data/lib/vigilem/support/lazy_simple_delegator.rb +81 -0
- data/lib/vigilem/support/max_size_error.rb +17 -0
- data/lib/vigilem/support/metadata.rb +13 -0
- data/lib/vigilem/support/obj_space.rb +28 -0
- data/lib/vigilem/support/patch/cucumber/c_lexer.rb +30 -0
- data/lib/vigilem/support/patch/ffi/pointer.rb +19 -0
- data/lib/vigilem/support/size_error.rb +6 -0
- data/lib/vigilem/support/sys.rb +5 -0
- data/lib/vigilem/support/system.rb +92 -0
- data/lib/vigilem/support/transmutable_hash.rb +206 -0
- data/lib/vigilem/support/utils.rb +224 -0
- data/lib/vigilem/support/version.rb +5 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/vigilem/ffi/array_pointer_sync_spec.rb +728 -0
- data/spec/vigilem/ffi/struct_spec.rb +22 -0
- data/spec/vigilem/ffi/utils/struct_spec.rb +79 -0
- data/spec/vigilem/ffi/utils_spec.rb +240 -0
- data/spec/vigilem/support/core_ext/enumerable_spec.rb +38 -0
- data/spec/vigilem/support/data/cached.kmap +130 -0
- data/spec/vigilem/support/data/cached_UTF-8_del.kmap +142 -0
- data/spec/vigilem/support/data/cached_short.kmap +38 -0
- data/spec/vigilem/support/data/dump_keys_short.kmap +128 -0
- data/spec/vigilem/support/key_map_spec.rb +767 -0
- data/spec/vigilem/support/lazy_simple_delegator_spec.rb +77 -0
- data/spec/vigilem/support/obj_space_spec.rb +47 -0
- data/spec/vigilem/support/sys_spec.rb +21 -0
- data/spec/vigilem/support/system_spec.rb +31 -0
- data/spec/vigilem/support/transmutable_hash_spec.rb +175 -0
- data/spec/vigilem/support/utils_spec.rb +214 -0
- metadata +240 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
module Vigilem
|
2
|
+
module Support
|
3
|
+
#
|
4
|
+
#
|
5
|
+
class KeyMapInfo
|
6
|
+
|
7
|
+
#
|
8
|
+
# @param [Hash] opts
|
9
|
+
def initialize(attrs={})
|
10
|
+
attrs.each {|attr| send(:"#{attr}=", opts[attr]) }
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# @return [Array<Symbol>]
|
15
|
+
def self.attrs
|
16
|
+
@attrs ||= [:keycode_range, :max_actions,
|
17
|
+
:number_of_functions_keys, :keymaps_in_use,
|
18
|
+
:max_compose_defs, :compose_defs,
|
19
|
+
:compose_defs_in_use, :mod_weights, :keysyms]
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_accessor *attrs
|
23
|
+
|
24
|
+
#
|
25
|
+
# @param [String] str
|
26
|
+
# @return [KeyMapInfo]
|
27
|
+
def self.load_string(str)
|
28
|
+
(kmi = new).load_string(str)
|
29
|
+
kmi
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# @param [String] str
|
34
|
+
# @return
|
35
|
+
def load_string(str)
|
36
|
+
str.lines do |substr|
|
37
|
+
case substr
|
38
|
+
when /^keycode range supported by kernel:/
|
39
|
+
keycode_range = substr.split(/:\s+/).last.rstrip
|
40
|
+
when /^max number of actions bindable to a key:/
|
41
|
+
max_actions = substr.split(/:\s+/).last.rstrip
|
42
|
+
when /^number of keymaps in actual use:/
|
43
|
+
keymaps_in_use = substr.split(/:\s+/).last.rstrip
|
44
|
+
when /^number of function keys supported by kernel:/
|
45
|
+
number_of_function_keys = substr.split(/:\s+/).last.rstrip
|
46
|
+
when /^max nr of compose definitions:/
|
47
|
+
max_compose_defs = substr.split(/:\s+/).last.rstrip
|
48
|
+
when /^nr of compose definitions in actual use:/
|
49
|
+
compose_defs_in_use = substr.split(/:\s+/).last.rstrip
|
50
|
+
when /^0x0[\dA-z]+/
|
51
|
+
hex_str, sym = substr.split(/\s+/)
|
52
|
+
keysyms[hex_str] = sym.rstrip
|
53
|
+
when /[a-z_]\s+for/i
|
54
|
+
# synonyms
|
55
|
+
when /^(shift|alt|control|ctrl|capsshift)(l|r|gr)?/
|
56
|
+
mod, col = substr.split(/\s+/)
|
57
|
+
mod_weights[mod] = col.rstrip.to_i
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# @return [Hash]
|
64
|
+
def keysyms
|
65
|
+
@keysyms ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
#
|
70
|
+
# @return [Hash]
|
71
|
+
def char_refs
|
72
|
+
keysyms.invert
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# @return [Hash]
|
77
|
+
def mod_weights
|
78
|
+
@mod_weights ||= {}
|
79
|
+
end
|
80
|
+
|
81
|
+
alias_method :mod_columns, :mod_weights
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Vigilem
|
4
|
+
module Support
|
5
|
+
#
|
6
|
+
# a Delegator that allows it's delegate to be named later (after init)
|
7
|
+
class LazySimpleDelegator < Delegator
|
8
|
+
|
9
|
+
methods_to_include = [:to_s, :inspect, :==, :===, :<=>, :eql?, :object_id]
|
10
|
+
|
11
|
+
(kd = ::Kernel.dup).class_eval do
|
12
|
+
((private_instance_methods | instance_methods) - methods_to_include).each do |m|
|
13
|
+
remove_method m
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
include kd
|
18
|
+
|
19
|
+
attr_writer :strict_eql
|
20
|
+
|
21
|
+
# @param obj, the delegate
|
22
|
+
def initialize(obj=nil)
|
23
|
+
super(obj) if obj
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# @return [self]
|
28
|
+
def use_strict_eql
|
29
|
+
@strict_eql = true
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# @return [TrueClass || FalseClass]
|
35
|
+
def strict_eql?
|
36
|
+
@strict_eql ||= false
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# @see Delegator
|
41
|
+
# @return obj the underlying object to delegate to
|
42
|
+
def __getobj__
|
43
|
+
@delegate_sd_obj
|
44
|
+
end
|
45
|
+
|
46
|
+
# more visually apeeling..............#sorry
|
47
|
+
alias_method :peel, :__getobj__
|
48
|
+
|
49
|
+
# change the object delegate to obj
|
50
|
+
# @see Delegator
|
51
|
+
# @param obj the object to delegate to
|
52
|
+
def __setobj__(obj)
|
53
|
+
raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
|
54
|
+
@delegate_sd_obj = obj
|
55
|
+
end
|
56
|
+
|
57
|
+
# compares #object_id's if #strict_eql?
|
58
|
+
# compares the other object against @delegate_sd_obj, what are the side effects?
|
59
|
+
# @return [TrueClass || FalseClass]
|
60
|
+
def eql?(other)
|
61
|
+
# @note Facets::Kerenl::respond munges the object_id
|
62
|
+
if other.respond_to?(:__getobj__)
|
63
|
+
if strict_eql?
|
64
|
+
self.__getobj__.object_id.eql? other.__getobj__.object_id
|
65
|
+
else
|
66
|
+
self.__getobj__.eql? other.__getobj__
|
67
|
+
end
|
68
|
+
else
|
69
|
+
if strict_eql?
|
70
|
+
self.__getobj__.object_id.eql? other.object_id
|
71
|
+
else
|
72
|
+
self.__getobj__.eql? other
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end #eql?
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'vigilem/support/size_error'
|
2
|
+
|
3
|
+
#
|
4
|
+
#
|
5
|
+
module Vigilem::Support
|
6
|
+
class MaxSizeError < SizeError
|
7
|
+
|
8
|
+
#
|
9
|
+
# @param [Array || Hash] obj_and_max_size
|
10
|
+
# @option :obj
|
11
|
+
# @option :max_size
|
12
|
+
def initialize(obj_and_max_size)
|
13
|
+
obj_and_max_size = Hash[obj_and_max_size.zip([:obj, :max_size]).map(&:reverse)] if obj_and_max_size.is_a? Array
|
14
|
+
super("size cannot exceed #{obj_and_max_size[:max_size]} for #{obj_and_max_size[:obj]}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'vigilem/support/core_ext'
|
2
|
+
|
3
|
+
module Vigilem
|
4
|
+
module Support
|
5
|
+
#
|
6
|
+
# ObjectSpace like methods
|
7
|
+
module ObjSpace
|
8
|
+
|
9
|
+
#
|
10
|
+
# @return [Array]
|
11
|
+
def all
|
12
|
+
@all ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# @param component
|
17
|
+
# @return [Array]
|
18
|
+
def obj_register(component)
|
19
|
+
self.all << component
|
20
|
+
if defined?(superclass) and superclass.respond_to? :obj_register
|
21
|
+
superclass.obj_register(component)
|
22
|
+
end
|
23
|
+
component
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module Gherkin
|
4
|
+
module CLexer
|
5
|
+
def self.singleton_method_added(method_name)
|
6
|
+
if method_name == :[] and not @overriden
|
7
|
+
@overriden = true
|
8
|
+
define_singleton_method(:[]) do |i18n_underscored_iso_code|
|
9
|
+
begin
|
10
|
+
prefix = if RbConfig::CONFIG['arch'] =~ /mswin|mingw/ && RbConfig::CONFIG['target_vendor'] != 'w64'
|
11
|
+
"#{RbConfig::CONFIG['MAJOR']}.#{RbConfig::CONFIG['MINOR']}/"
|
12
|
+
else
|
13
|
+
''
|
14
|
+
end
|
15
|
+
|
16
|
+
lib = "#{prefix}gherkin_lexer_#{i18n_underscored_iso_code}"
|
17
|
+
require lib
|
18
|
+
const_get(i18n_underscored_iso_code.capitalize)
|
19
|
+
rescue LoadError => e
|
20
|
+
e.message << %{\nCouldn't load #{lib}\nThe $LOAD_PATH was:\n#{$LOAD_PATH.join("\n")}}
|
21
|
+
raise e
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
super(method_name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'ffi/pointer'
|
3
|
+
|
4
|
+
module FFI
|
5
|
+
class Pointer
|
6
|
+
def ==(other_obj)
|
7
|
+
return true if self.eql?(other_obj)
|
8
|
+
if other_obj.respond_to? :bytes
|
9
|
+
self.read_bytes(self.size) == other_obj.bytes
|
10
|
+
elsif other_obj.respond_to? :read_bytes and
|
11
|
+
other_obj.respond_to? :size
|
12
|
+
self.read_bytes(self.size) == other_obj.read_bytes(other_obj.size)
|
13
|
+
else
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Vigilem
|
2
|
+
module Support
|
3
|
+
#
|
4
|
+
# System detection utilities
|
5
|
+
module System
|
6
|
+
|
7
|
+
SYSTEM_NAME_MASKS = { :mac => /darwin/, :windows => (win = Gem::WIN_PATTERNS.join('|')),
|
8
|
+
:win => win, :linux => /linux/, :bsd => /bsd/,
|
9
|
+
:nix => /nix|solaris|darwin|bsd|aix|hpux/, :aix => /aix/ }
|
10
|
+
#:java => /java/}
|
11
|
+
|
12
|
+
#
|
13
|
+
# @todo FFI::Platform || Fiddle::WINDOWS
|
14
|
+
# generates os_name? methods
|
15
|
+
# @return [Regexp]
|
16
|
+
SYSTEM_NAME_MASKS.each do |mask_name, mask|
|
17
|
+
define_method(:"#{mask_name}?") do
|
18
|
+
os =~ SYSTEM_NAME_MASKS[mask_name]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
def os
|
25
|
+
RbConfig::CONFIG['host_os']
|
26
|
+
end
|
27
|
+
|
28
|
+
# this will may mis-represent check out https://bugs.ruby-lang.org/issues/8568
|
29
|
+
# the size of a long
|
30
|
+
# @return [Integer]
|
31
|
+
def long_length
|
32
|
+
@long_len ||= [0].pack('L!').bytesize
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# @return [TrueClass || FalseClass]
|
37
|
+
def x64bit?
|
38
|
+
@x64_bit ||= [nil].pack('p').bytesize == 8
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# @return [TrueClass || FalseClass]
|
43
|
+
def x32bit?
|
44
|
+
not self.x64bit?
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# @return [TrueClass || FalseClass]
|
49
|
+
def big_endian?
|
50
|
+
[1].pack('I') == [1].pack('N')
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# @return [TrueClass || FalseClass]
|
55
|
+
def little_endian?
|
56
|
+
!big_endian?
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# @param [Numeric] number
|
61
|
+
# @return the same number converted to a native signed long
|
62
|
+
def native_signed_long(number)
|
63
|
+
[number].pack('l!').unpack('l!').first
|
64
|
+
end
|
65
|
+
|
66
|
+
PACKVAR = 'ABCDEFGHILMNPQSUVWXZ'
|
67
|
+
|
68
|
+
# replace/supplement with Fiddle::Importer#sizeof, ruby2c, MakeMakefile#check_sizeof
|
69
|
+
# @see String#unpack
|
70
|
+
# @see Array#pack
|
71
|
+
# @param [String] format
|
72
|
+
# @return [Integer] the fize of the format
|
73
|
+
def sizeof(format)
|
74
|
+
# Only for numeric formats, String formats will raise a TypeError
|
75
|
+
elements = 0
|
76
|
+
format.scan(/[#{PACKVAR}]_?\d*/i) do |mtch|
|
77
|
+
if mtch =~ /\d+/
|
78
|
+
elements += mtch.gsub('_', '')[1..-1].to_i
|
79
|
+
elsif mtch !~ /!|_/
|
80
|
+
elements += 1
|
81
|
+
end
|
82
|
+
end
|
83
|
+
([ 0 ] * elements).pack(format).length # bytesize?
|
84
|
+
end
|
85
|
+
|
86
|
+
extend self
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
require 'vigilem/support/sys'
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Vigilem
|
4
|
+
module Support
|
5
|
+
# A transmutable Hash, Splits arrays into multiple keys with the same value
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# {"a"=>:key1, "b"=>:key1, "c"=>:key1, "d"=>:key, "e"=>:key2, "f"=>:key2}
|
9
|
+
# becomes
|
10
|
+
#
|
11
|
+
# {:key1=>["a", "b", "c"], :key2=>["e", "f"], :key => "d"}
|
12
|
+
#
|
13
|
+
# And
|
14
|
+
#
|
15
|
+
# {:key1=>["a", "b", "c"], :key2=>["d", "e", "f"]}
|
16
|
+
# becomes
|
17
|
+
#
|
18
|
+
# {"a"=>:key1, "b"=>:key1, "c"=>:key1, "d"=>:key, "e"=>:key2, "f"=>:key2}
|
19
|
+
# And
|
20
|
+
#
|
21
|
+
# {:key1=> ['a' , ['b', 'c']]}
|
22
|
+
# becomes
|
23
|
+
#
|
24
|
+
# {"a"=>:key1, ["b", 'c']=>:key1 }
|
25
|
+
#
|
26
|
+
class TransmutableHash < Hash
|
27
|
+
|
28
|
+
extend Forwardable
|
29
|
+
|
30
|
+
# @param [Hash] hsh_or_default_value
|
31
|
+
# @param default_value
|
32
|
+
# @param [Proc] default_proc
|
33
|
+
def initialize(hsh_or_default_value={}, default_value=nil, &default_proc)
|
34
|
+
hsh, dfault = if hsh_or_default_value.is_a?(Hash)
|
35
|
+
[hsh_or_default_value, default_value]
|
36
|
+
else
|
37
|
+
[{}, hsh_or_default_value]
|
38
|
+
end
|
39
|
+
super(*dfault, &default_proc).merge!(hsh)
|
40
|
+
self.invert_default = self.default
|
41
|
+
self.invert_default_proc = self.default_proc if default_proc
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# it will have a different object_id, because technically its a different hash
|
46
|
+
# not sure if that's a bug
|
47
|
+
# @return [Hash]
|
48
|
+
def invert
|
49
|
+
# did self change?
|
50
|
+
if _hash_cache_ != (temp_cache = hash)
|
51
|
+
_hash_cache_ = temp_cache
|
52
|
+
_invert_cache_ = self.class.transmute(self)
|
53
|
+
end
|
54
|
+
# if it didn't change pass off the _invert_cache_
|
55
|
+
_invert_cache_
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
#
|
60
|
+
def inverted?
|
61
|
+
@inverted ||= false
|
62
|
+
end
|
63
|
+
|
64
|
+
# in-place version of #invert
|
65
|
+
#
|
66
|
+
# @see TransmutableHash#invert
|
67
|
+
# @return [Hash]
|
68
|
+
def invert!
|
69
|
+
@inverted = !@inverted
|
70
|
+
self.class[replace(invert)]
|
71
|
+
end
|
72
|
+
|
73
|
+
class << self
|
74
|
+
#
|
75
|
+
#
|
76
|
+
# @param [Hash] in_hash
|
77
|
+
# @param [Hash] dest_hash
|
78
|
+
# @return [Hash] dest_hash
|
79
|
+
def transmute(in_hash, dest_hash={})
|
80
|
+
in_hash.each do |old_key, old_value|
|
81
|
+
if old_value.is_a? Array
|
82
|
+
old_value.uniq.each {|new_key| fuse_value(dest_hash, new_key, old_key) }
|
83
|
+
else
|
84
|
+
fuse_value(dest_hash, old_value, old_key)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
self[dest_hash]
|
88
|
+
end
|
89
|
+
|
90
|
+
# creating somthing like ['keycode1', 'altgr', 'keycode1']
|
91
|
+
# @param [Hash] hsh
|
92
|
+
# @param key
|
93
|
+
# @param value
|
94
|
+
# @return value
|
95
|
+
def fuse_value(hsh, key, value)
|
96
|
+
if hsh.has_key?(key)
|
97
|
+
if (current_val = hsh[key]).is_a? Array
|
98
|
+
current_val.concat([value])
|
99
|
+
else
|
100
|
+
hsh[key] = [current_val, value]
|
101
|
+
end
|
102
|
+
elsif value.is_a? Array
|
103
|
+
hsh[key] = [value]
|
104
|
+
else
|
105
|
+
hsh[key] = value
|
106
|
+
end
|
107
|
+
self[hsh]
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# @param [Array<Hash>]
|
114
|
+
# @return
|
115
|
+
def fuse!(*hashes)
|
116
|
+
hashes.each do |hsh|
|
117
|
+
hsh.each do |k, v|
|
118
|
+
self.class.fuse_value(self, k, v)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# @param [Array<Hash>]
|
126
|
+
# @return
|
127
|
+
def fuse(*hashes)
|
128
|
+
container = self.class.new
|
129
|
+
hashes.each do |hsh|
|
130
|
+
hsh.each do |k, v|
|
131
|
+
self.fuse_value(hsh, k, v)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
container.defaults = self.defaults
|
135
|
+
container.default_procs = self.default_procs
|
136
|
+
container.fuze!(*hashes)
|
137
|
+
end
|
138
|
+
|
139
|
+
# fetches from the Hash all the values that have keys that match
|
140
|
+
# the Regexp kind of like grep
|
141
|
+
# @param [Regexp] regex
|
142
|
+
# @param [Integer] limit
|
143
|
+
# @return [Array]
|
144
|
+
def regex_fetch(regex, limit=nil)
|
145
|
+
limit ||= -1
|
146
|
+
key_list = self.keys.map {|key| [*key].grep(regex) }[0..limit].compact
|
147
|
+
key_list.map {|key| self[key] }
|
148
|
+
end
|
149
|
+
|
150
|
+
def_delegator :_invert_cache_, :default=, :invert_default=
|
151
|
+
def_delegator :_invert_cache_, :default, :invert_default
|
152
|
+
def_delegator :_invert_cache_, :default_proc=, :invert_default_proc=
|
153
|
+
def_delegator :_invert_cache_, :default_proc, :invert_default_proc
|
154
|
+
|
155
|
+
alias_method :uninvert_default=, :default=
|
156
|
+
alias_method :uninvert_default, :default
|
157
|
+
alias_method :uninvert_default_proc=, :default_proc=
|
158
|
+
alias_method :uninvert_default_proc, :default_proc
|
159
|
+
|
160
|
+
# sets the default for both self and the inverted_cache
|
161
|
+
# @see Hash#default=
|
162
|
+
# @param objs
|
163
|
+
# @return objs
|
164
|
+
def defaults=(objs)
|
165
|
+
send(:default=, [*objs].first)
|
166
|
+
_invert_cache_.default = [*objs].last
|
167
|
+
objs
|
168
|
+
end
|
169
|
+
|
170
|
+
# gets the default for both self and the inverted_cache
|
171
|
+
# @return [Array]
|
172
|
+
def defaults
|
173
|
+
[default(), invert_default]
|
174
|
+
end
|
175
|
+
|
176
|
+
# gets the default for both self and the inverted_cache
|
177
|
+
# @return [Array]
|
178
|
+
def default_procs
|
179
|
+
[default_proc(), invert_default_proc]
|
180
|
+
end
|
181
|
+
|
182
|
+
# sets the default for both self and the inverted_cache
|
183
|
+
# @param objs
|
184
|
+
# @return objs
|
185
|
+
def default_procs=(objs)
|
186
|
+
if fdprc = [*objs].first
|
187
|
+
send(:default_proc=, fdprc)
|
188
|
+
end
|
189
|
+
if ldprc = [*objs].last
|
190
|
+
_invert_cache_.default_proc = ldprc
|
191
|
+
end
|
192
|
+
objs
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
attr_accessor :_hash_cache_
|
197
|
+
attr_writer :_invert_cache_
|
198
|
+
|
199
|
+
# gets the cached version of the inverse
|
200
|
+
# @return [TransmutableHash]
|
201
|
+
def _invert_cache_
|
202
|
+
@_invert_cache_ ||= invert().tap {|obj| obj.instance_variable_set(:@inverted, true) }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|