vigilem-support 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|