Class: SubObject
- Inherits:
-
Object
- Object
- SubObject
- Defined in:
- lib/sub_object.rb,
lib/sub_object/sub_array.rb
Overview
Parent class for SubString and SubObject::SubArray or similar.
Summary
This class SubObject is the parent class for SubString and alike. This class expresses Ruby sub-Object (like Sub-String), which are obtained with the self[i, j] method, but taking up negligible memory space, as its instance internally holds the (likely positional, though arbitrary) information (i, j) only. It provides the basic interface so the instance behaves exactly like the original class (String for SubString, for example) as duck-typing, except destructive modification, which is prohibited.
If the original object is destructively modified in a way it changes its hash value, warning is issued whenever this instance is accessed.
Important note to the developers
To inherit this class, make sure to include the lines equivalent to the following 2 lines, replacing the method name :to_str (which is for SubString class) to suit your child class.
TO_SOURCE_METHOD = :to_str
alias_method TO_SOURCE_METHOD, :to_source
The full reference is found in the top page SubObject and in Github
Direct Known Subclasses
Defined Under Namespace
Classes: SubArray
Constant Summary collapse
- TO_SOURCE_METHOD =
Symbol of the method that projects to (returns) the original-like instance; e.g., :to_str for String. The value should be overwritten in the child class of SubObject.
:itself- DESTRUCTIVE_METHODS =
List of the names (String) of destructive methods (other than those ending with “!”).
%w( []= << clear concat force_encoding insert prepend replace )
Instance Attribute Summary collapse
-
#attr ⇒ Object
Setter/Getter of the attribute.
-
#pos ⇒ Object
readonly
Starting (character) position.
Class Method Summary collapse
-
.verbose ⇒ Object
Getter of the class instance variable @verbosity.
-
.verbose=(obj) ⇒ Object
Setter of the class instance variable @@verbosity.
Instance Method Summary collapse
-
#<=>(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source.
-
#==(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source.
-
#===(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source.
-
#=~(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source.
-
#initialize(source, pos, size, attr: nil) ⇒ SubObject
constructor
Returns a new instance of SubObject equivalent to source[ pos, size ].
- #inspect ⇒ String
- #inspect_before_sub_object ⇒ Object
-
#is_a?(*rest) ⇒ Boolean
Redefining a method in Object to evaluate via #to_source.
-
#kind_of?(*rest) ⇒ Boolean
Redefining a method in Object to evaluate via #to_source.
-
#method_missing(method_name, *rest, &block) ⇒ Object
method_missing for any but destructive methods.
- #pos_size ⇒ Aray
-
#respond_to_missing?(method_name, *rest) ⇒ Boolean
Obligatory redefinition, following redefined #method_missing.
-
#source ⇒ Object
Frozen String returned.
-
#subsize ⇒ Object
Usually the size (Integer).
-
#to_s(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source.
-
#to_source ⇒ Object
Returns the original representation of the instance as in the source.
Constructor Details
#initialize(source, pos, size, attr: nil) ⇒ SubObject
Returns a new instance of SubObject equivalent to source[ pos, size ]
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/sub_object.rb', line 92 def initialize(source, pos, size, attr: nil) @source, @pos, @isize = source, pos, size @attr = attr # Sanity check begin _ = @source[@pos, @isize] rescue NoMethodError raise TypeError, ERR_MSGS[:no_method_error] rescue ArgumentError raise TypeError, ERR_MSGS[:argument_error] rescue TypeError raise TypeError, ERR_MSGS[:type_error]%[pos.inspect, size.inspect] end if !source.respond_to? self.class::TO_SOURCE_METHOD raise TypeError, "Wrong source class #{source.class.name} for this class #{self.class.name}" end # Hash value retained to check its potential destructive change @hash = @source.hash end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *rest, &block) ⇒ Object
method_missing for any but destructive methods
191 192 193 |
# File 'lib/sub_object.rb', line 191 def method_missing(method_name, *rest, &block) destructive_method?(method_name) ? super : to_source.send(method_name, *rest, &block) end |
Instance Attribute Details
#attr ⇒ Object
Setter/Getter of the attribute. nil in default.
85 86 87 |
# File 'lib/sub_object.rb', line 85 def attr @attr end |
#pos ⇒ Object (readonly)
Starting (character) position
82 83 84 |
# File 'lib/sub_object.rb', line 82 def pos @pos end |
Class Method Details
.verbose ⇒ Object
Getter of the class instance variable @verbosity
61 62 63 |
# File 'lib/sub_object.rb', line 61 def self.verbose (defined? @verbosity) ? @verbosity : nil end |
.verbose=(obj) ⇒ Object
Setter of the class instance variable @@verbosity
66 67 68 |
# File 'lib/sub_object.rb', line 66 def self.verbose=(obj) @verbosity=obj end |
Instance Method Details
#<=>(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
175 |
# File 'lib/sub_object.rb', line 175 def <=>( *rest); to_source.send(__method__, *rest); end |
#==(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
165 |
# File 'lib/sub_object.rb', line 165 def ==( *rest); to_source.send(__method__, *rest); end |
#===(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
167 |
# File 'lib/sub_object.rb', line 167 def ===( *rest); to_source.send(__method__, *rest); end |
#=~(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
173 |
# File 'lib/sub_object.rb', line 173 def =~( *rest); to_source.send(__method__, *rest); end |
#inspect ⇒ String
182 183 184 185 |
# File 'lib/sub_object.rb', line 182 def inspect warn_hash sprintf('%s[%d,%d]%s', self.class.name.split(/::/)[-1], @pos, @isize, @source[@pos, @isize].inspect) end |
#inspect_before_sub_object ⇒ Object
179 |
# File 'lib/sub_object.rb', line 179 alias_method :inspect_before_sub_object, :inspect |
#is_a?(*rest) ⇒ Boolean
Redefining a method in Object to evaluate via #to_source
169 |
# File 'lib/sub_object.rb', line 169 def is_a?( *rest); to_source.send(__method__, *rest); end |
#kind_of?(*rest) ⇒ Boolean
Redefining a method in Object to evaluate via #to_source
171 |
# File 'lib/sub_object.rb', line 171 def kind_of?(*rest); to_source.send(__method__, *rest); end |
#pos_size ⇒ Aray
116 117 118 |
# File 'lib/sub_object.rb', line 116 def pos_size [@pos, @isize] end |
#respond_to_missing?(method_name, *rest) ⇒ Boolean
Obligatory redefinition, following redefined #method_missing
196 197 198 |
# File 'lib/sub_object.rb', line 196 def respond_to_missing?(method_name, *rest) destructive_method?(method_name) ? super : to_source.send(:respond_to?, method_name, *rest) end |
#source ⇒ Object
Frozen String returned.
126 127 128 129 130 131 |
# File 'lib/sub_object.rb', line 126 def source warn_hash src = @source.dup src.freeze src end |
#subsize ⇒ Object
Returns usually the size (Integer).
121 122 123 |
# File 'lib/sub_object.rb', line 121 def subsize @isize end |
#to_s(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
177 |
# File 'lib/sub_object.rb', line 177 def to_s( *rest); to_source.send(__method__, *rest); end |
#to_source ⇒ Object
Returns the original representation of the instance as in the source
Each child class should set the constant TO_SOURCE_METHOD appropriately and should alias this method to the method registered to TO_SOURCE_METHOD . For example, for SubString,
TO_SOURCE_METHOD = :to_str
alias_method TO_SOURCE_METHOD, :to_source
Warning: DO NOT OVERWRITE THIS METHOD.
145 146 147 148 |
# File 'lib/sub_object.rb', line 145 def to_source warn_hash @source[@pos, @isize].send(to_source_method) end |