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 ]
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/sub_object.rb', line 93 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
192 193 194 |
# File 'lib/sub_object.rb', line 192 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
176 |
# File 'lib/sub_object.rb', line 176 def <=>( *rest); to_source.send(__method__, *rest); end |
#==(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
166 |
# File 'lib/sub_object.rb', line 166 def ==( *rest); to_source.send(__method__, *rest); end |
#===(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
168 |
# File 'lib/sub_object.rb', line 168 def ===( *rest); to_source.send(__method__, *rest); end |
#=~(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
174 |
# File 'lib/sub_object.rb', line 174 def =~( *rest); to_source.send(__method__, *rest); end |
#inspect ⇒ String
183 184 185 186 |
# File 'lib/sub_object.rb', line 183 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
180 |
# File 'lib/sub_object.rb', line 180 alias_method :inspect_before_sub_object, :inspect |
#is_a?(*rest) ⇒ Boolean
Redefining a method in Object to evaluate via #to_source
170 |
# File 'lib/sub_object.rb', line 170 def is_a?( *rest); to_source.send(__method__, *rest); end |
#kind_of?(*rest) ⇒ Boolean
Redefining a method in Object to evaluate via #to_source
172 |
# File 'lib/sub_object.rb', line 172 def kind_of?(*rest); to_source.send(__method__, *rest); end |
#pos_size ⇒ Aray
117 118 119 |
# File 'lib/sub_object.rb', line 117 def pos_size [@pos, @isize] end |
#respond_to_missing?(method_name, *rest) ⇒ Boolean
Obligatory redefinition, following redefined #method_missing
197 198 199 |
# File 'lib/sub_object.rb', line 197 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.
127 128 129 130 131 132 |
# File 'lib/sub_object.rb', line 127 def source warn_hash src = @source.dup src.freeze src end |
#subsize ⇒ Object
Returns usually the size (Integer).
122 123 124 |
# File 'lib/sub_object.rb', line 122 def subsize @isize end |
#to_s(*rest) ⇒ Object
Redefining a method in Object to evaluate via #to_source
178 |
# File 'lib/sub_object.rb', line 178 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.
146 147 148 149 |
# File 'lib/sub_object.rb', line 146 def to_source warn_hash @source[@pos, @isize].send(to_source_method) end |