sub_object 1.0.2 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14346f60c61e9934272e9530515e99e0956658831291d1982a7941f507e30190
4
- data.tar.gz: 20eb48e09c3b0287e88f81dc3921f436809dd391a3637eccf47f8c6f1a60d875
3
+ metadata.gz: 82f0b7dfe21acc55f95a85ede284e7726a2d20b8167933a64f2d19326a603881
4
+ data.tar.gz: f38d6e5d31d7c2db961bde8324d94f567f50f00ba07deb8c31df45a24cb08471
5
5
  SHA512:
6
- metadata.gz: ecc193b15d20eaee183536ee892a02150e1e079622b1b8576cd1d3d6aa13c90ba88906348c46ceecdca8f4195274848e1c7c9877f6aa06edacbd2e8cf902c44f
7
- data.tar.gz: fd77c5894e90aedda767e588419133840b2628d96faedfdac981eaf444c4ef14ec9964bb87ec6c1316f4e880d3a600534fbec9d76d4039feda77ee47e8485407
6
+ metadata.gz: 0a0af4d1e49ee3f2eeb91a7394c92e797a2911b08a29d5c515e245bc3568aeb7db507e2ac2893894fda41662b8ed9d75a25ab369967368f265664eecc274984d
7
+ data.tar.gz: c25e3f02f129a10efc1ae05127cf513f4cb627d4941c0f408cded27b1eade3efd0543dd9c05da09f4cb20e73f30907965303f32732ee4237ade69200114e8053
data/ChangeLog CHANGED
@@ -1,3 +1,8 @@
1
+ -----
2
+ (Version: 1.1)
3
+ 2019-11-09 Masa Sakano
4
+ * Added attr getter/setter and initializer.
5
+
1
6
  -----
2
7
  (Version: 1.0.2)
3
8
  2019-11-07 Masa Sakano
data/Makefile CHANGED
@@ -20,5 +20,5 @@ test:
20
20
 
21
21
  ## yard2md_afterclean in Gem plain_text https://rubygems.org/gems/plain_text
22
22
  doc:
23
- yard doc; [[ -x ".github" && ( "README.en.rdoc" -nt ".github/README.md" ) ]] && ( ruby -r rdoc -e 'puts RDoc::Markup::ToMarkdown.new.convert ARGF.read' < README.en.rdoc | yard2md_afterclean > .github/README.md ; echo ".github/README.md is updated." ) || exit 0
23
+ yard doc; [[ -x ".github" && ( "README.en.rdoc" -nt ".github/README.md" ) ]] && ( ruby -r rdoc -e 'puts RDoc::Markup::ToMarkdown.new.convert ARGF.read' < README.en.rdoc | yard2md_afterclean > .github/README.md.$$ && ( mv -f .github/README.md.$$ .github/README.md && echo ".github/README.md is updated." ) || ( echo "ERROR: failed to create .github/README.md" >&2 ) ) || exit 0
24
24
 
data/README.en.rdoc CHANGED
@@ -3,15 +3,16 @@
3
3
 
4
4
  == Summary
5
5
 
6
- This class {SubObject} is the parent class for
6
+ This class {SubObject}[http://rubygems.org/gems/sub_object] is the parent class for
7
7
  {SubString}[http://rubygems.org/gems/sub_string] and alike.
8
8
  This class expresses Ruby sub-Object (like Sub-String),
9
- which are obtained with the +self[i, j]+ method,
9
+ which are obtained with the +self[ i, j ]+ method,
10
10
  but taking up negligible memory space, as its instance internally holds
11
11
  the (likely positional, though arbitrary) information +(i, j)+ only. This class provides the base
12
12
  interface so the instance behaves exactly like the original
13
13
  class (String for SubString, for example) as duck-typing, except
14
- destructive modification, which is prohibited.
14
+ destructive modification, which is prohibited. Also, as a bonus, an
15
+ arbitrary object can be associated with instances of this class with {SubObject#attr}.
15
16
 
16
17
  If the original object (which an instance of this class refers to) is ever destructively modified in a way it changes
17
18
  its hash value, warning will be issued whenever this instance is accessed.
@@ -30,7 +31,7 @@ SubString class) to suit your child class.
30
31
  TO_SOURCE_METHOD = :to_str
31
32
  alias_method TO_SOURCE_METHOD, :to_source
32
33
 
33
- == Cencept
34
+ == Concept
34
35
 
35
36
  This class takes three parameters in the initialization: *source*, *pos*
36
37
  (position), and *size*. *source* is the original object, and
@@ -80,10 +81,10 @@ Therefore, whenever a destructive method is applied, this class tries
80
81
  to raise NoMethodError exception. The routine to identify the
81
82
  destructive method relies thoroughly on the method name.
82
83
  The methods ending with "!" are regarded as destructive.
83
- Other standard distructive method names are defined in the constant {SubObject::DESTRUCTIVE_METHODS}.
84
+ Other standard destructive method names are defined in the constant {SubObject::DESTRUCTIVE_METHODS}.
84
85
  Each child class may add entries or modify it.
85
86
 
86
- Note that if a (likely user-defined) desturctive method passes the check,
87
+ Note that if a (likely user-defined) destructive method passes the check,
87
88
  the result is most likely to be different from intended. It certainly
88
89
  never alters this instance destructively (unless +[]+ method of the
89
90
  source object returns self, which is against the Ruby convention), and
@@ -108,7 +109,7 @@ according to the length of the sub-String. Consider an example:
108
109
 
109
110
  The variable +sub+ uses up about the same memory of +src+.
110
111
  If a great number of +sub+ is created and held alive, the total memory
111
- used by the process can become quicly multifold, even by orders of magnitude.
112
+ used by the process can become quickly multifold, even by orders of magnitude.
112
113
 
113
114
  This is where this class comes in handy. For example, a parsing
114
115
  program applied to a huge text document with a complex grammar may
@@ -117,9 +118,12 @@ of String, it can save some valuable memory.
117
118
 
118
119
  That is precisely why
119
120
  {SubString}[http://rubygems.org/gems/sub_string],
120
- which is a child class of this class and for String, is registered as an official Gem.
121
+ which is a child class of this class and for String, is registered as a separate official Gem.
121
122
  (In practice, this class is a generalised version of *SubString*,
122
- which Ruby allows as a flexible programming language!)
123
+ which Ruby allows, being a flexible programming language!)
124
+
125
+ Note this class also offers a function to associate an arbitrary
126
+ object with it with the setter and getter methods of {SubObject#attr=} and {SubObject#attr}.
123
127
 
124
128
  == Description
125
129
 
@@ -127,12 +131,18 @@ which Ruby allows as a flexible programming language!)
127
131
 
128
132
  Initialize as follows:
129
133
 
130
- SubObject.new( source, index1, index2 )
134
+ SubObject.new( source, index1, index2, attr: your_object )
131
135
 
132
136
  Usually, +index1+ is the starting index and +index2+ is the size,
133
137
  though how they should be recognized depends on the definition of the method
134
138
  +[i,j]+ of +source+.
135
139
 
140
+ +attr+ option is optional and to set an arbitrary object as an
141
+ instance variable. The default value is nil. It can be
142
+ reset any time later with the setter method of {SubObject#attr=}.
143
+ To store an arbitrary number of pieces of information, a Hash instance
144
+ would be convenient.
145
+
136
146
  === Constant
137
147
 
138
148
  {SubObject::DESTRUCTIVE_METHODS}:: This public constant is the array holding the list of the names (as String) of the methods that should be recognized as destructive (other than those ending with "!").
@@ -141,27 +151,27 @@ though how they should be recognized depends on the definition of the method
141
151
  The class variable +TO_SOURCE_METHOD+ is meant to be set by each
142
152
  child class (and child classes only). For example, if it is the subclass for String, it should
143
153
  be +:to_str+. Specifically, the registered method must respond to
144
- +source[i,j]+. Nott that in this class (parent class), it is **left unset**, but the (private) method of the
154
+ +source[i,j]+. Note that in this class (parent class), it is **left unset**, but the (private) method of the
145
155
  same name +to_original_method+ returns +:itself+ instead.
146
156
 
147
157
  *WARNING*: Do not set this class variable in this class, as it could result in unexpected behaviours if
148
- a child class and the parent class are used simultaneously.
158
+ a child class and this class (parent) are used simultaneously.
149
159
 
150
160
 
151
161
  === Class-global settings and class methods
152
162
 
153
163
  When this class is accessed after any alteration of the original
154
- source object has been detected, it may issue warning (as the insntace does not make sense any more).
164
+ source object has been detected, it may issue warning (as the instance does not make sense any more).
155
165
  The warning is suppressed when the Ruby global variable +$VERBOSE+ is
156
166
  nil (it is false in Ruby default). Or, if the following setting is
157
- made (internaly, it sets/reads a class instance variable) and set non-nil,
167
+ made (internally, it sets/reads a class instance variable) and set non-nil,
158
168
  its value precedes +$VERBOSE+:
159
169
 
160
170
  SubObject.verbose # => getter
161
171
  SubObject.verbose=true # => setter
162
172
 
163
173
  where SubObject should be replaced with the name of your child class that inherits {SubObject}.
164
- If this value is true or false, such a warning is issued or suppresed,
174
+ If this value is true or false, such a warning is issued or suppressed,
165
175
  respectively, regardless of the value of the global variable +$VERBOSE+.
166
176
 
167
177
 
@@ -174,6 +184,8 @@ The following is the instance methods of {SubObject} unique to this class.
174
184
  +#subsize()+:: Returns the third argument given in initialization (usually meaning the size of the sub-"source"). Usually this is equivalent to the method +#size+; this method is introduced in case the class of the +source+ somehow does not have the +#size+ method.
175
185
  +#pos_size()+:: Returns the two-component array of +[pos, subsize]+
176
186
  +#to_source()+:: Returns the instance as close as the original +source+ (the class of it, etc).
187
+ +#attr=()+:: Setter of the user-defined instance variable.
188
+ +#attr()+:: Getter of the user-defined instance variable. The default is nil.
177
189
 
178
190
  In addition, {#inspect}[SubObject#inspect] is redefined.
179
191
 
@@ -201,7 +213,7 @@ Internally, almost any method that the instance receives, except for those speci
201
213
  the following order:
202
214
 
203
215
  1. {#method_missing}[SubObject#method_missing] (almost any methods except those defined in Object should be processed here)
204
- 1. +super+ if destuctive (usually NoMethodError, because Object class does not have "destructive" methods, though you may argue +taint+ etc is "destructive")
216
+ 1. +super+ if destructive (usually NoMethodError, because Object class does not have "destructive" methods, though you may argue +taint+ etc is "destructive")
205
217
  2. Else, +send+ to {#to_source}[SubObject#to_source]
206
218
  2. {#to_source}[SubObject#to_source]
207
219
  1. check whether the original {#source}[SubObject#source] has been altered and issues a warning if the conditions are met.
data/lib/sub_object.rb CHANGED
@@ -81,16 +81,17 @@ class SubObject
81
81
  # Starting (character) position
82
82
  attr_reader :pos
83
83
 
84
- # Size of SubObject. Identical with #size
85
- # attr_reader :isize
84
+ # Setter/Getter of the attribute. nil in default.
85
+ attr_accessor :attr
86
86
 
87
87
  # Returns a new instance of SubObject equivalent to source[ pos, size ]
88
88
  #
89
89
  # @param source [String]
90
90
  # @param pos [Integer]
91
91
  # @param size [Integer]
92
- def initialize(source, pos, size)
92
+ def initialize(source, pos, size, attr: nil)
93
93
  @source, @pos, @isize = source, pos, size
94
+ @attr = attr
94
95
 
95
96
  # Sanity check
96
97
  begin
data/sub_object.gemspec CHANGED
@@ -5,7 +5,7 @@ require 'date'
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'sub_object'.sub(/.*/){|c| (c == File.basename(Dir.pwd)) ? c : raise("ERROR: s.name=(#{c}) in gemspec seems wrong!")}
8
- s.version = "1.0.2".sub(/.*/){|c| fs = Dir.glob('changelog{,.*}', File::FNM_CASEFOLD); raise('More than one ChangeLog exist!') if fs.size > 1; warn("WARNING: Version(s.version=#{c}) already exists in #{fs[0]} - ok?") if fs.size == 1 && !IO.readlines(fs[0]).grep(/^\(Version: #{Regexp.quote c}\)$/).empty? ; c } # n.b., In macOS, changelog and ChangeLog are identical in default.
8
+ s.version = "1.1".sub(/.*/){|c| fs = Dir.glob('changelog{,.*}', File::FNM_CASEFOLD); raise('More than one ChangeLog exist!') if fs.size > 1; warn("WARNING: Version(s.version=#{c}) already exists in #{fs[0]} - ok?") if fs.size == 1 && !IO.readlines(fs[0]).grep(/^\(Version: #{Regexp.quote c}\)$/).empty? ; c } # n.b., In macOS, changelog and ChangeLog are identical in default.
9
9
  # s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
10
  # s.bindir = 'bin'
11
11
  # %w(sub_object).each do |f|
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  # File.executable?(path) ? s.executables << f : raise("ERROR: Executable (#{path}) is not executable!")
14
14
  # end
15
15
  s.authors = ["Masa Sakano"]
16
- s.date = %q{2019-11-07}.sub(/.*/){|c| (Date.parse(c) == Date.today) ? c : raise("ERROR: s.date=(#{c}) is not today!")}
16
+ s.date = %q{2019-11-09}.sub(/.*/){|c| (Date.parse(c) == Date.today) ? c : raise("ERROR: s.date=(#{c}) is not today!")}
17
17
  s.summary = %q{Parent class for memory-efficient sub-Something}
18
18
  s.description = %q{Class SubObject that is the parent class for Ruby SubString and SubArray classes and alike, providing the base interface. This and child classes use negligible memory space, as their instance holds the positional information only. It behaves exactly like the source object (duck-typing), except destructive modification is prohibited. If the original source object is destructively altered, the corresponding instance can detect it and issue warning.}
19
19
  # s.email = %q{abc@example.com}
@@ -101,6 +101,7 @@ class TestUnitSubObject < MiniTest::Test
101
101
  assert_equal MyC.new(myo.x+2+3), obj.to_source
102
102
  assert_equal "SubObject", obj.class.name
103
103
  assert_equal "6", obj.to_s
104
+ assert_nil obj.attr
104
105
  assert myo.respond_to?(:to_s)
105
106
  assert obj.respond_to?(:to_s)
106
107
  assert myo.respond_to?(:plus1)
@@ -173,6 +174,16 @@ class TestUnitSubObject < MiniTest::Test
173
174
  }
174
175
  }
175
176
  exclu.join
177
+
178
+ # Tests of attr
179
+ myo = MyC.new(1)
180
+ obj = SubObject.new myo, 2, 3, attr: 5
181
+ assert_equal 5, obj.attr
182
+ hs = Hash[{ try: 67 }]
183
+ obj.attr = hs
184
+ assert_equal hs, obj.attr
185
+ obj.attr[:try] = 89
186
+ assert_equal 89, obj.attr[:try]
176
187
  end
177
188
 
178
189
  def test_sub_array01
@@ -184,6 +195,7 @@ class TestUnitSubObject < MiniTest::Test
184
195
  assert_equal 2, obj.subsize
185
196
  assert_equal [-3, 2], obj.pos_size
186
197
  assert_equal ary[-3, 2], obj.to_source
198
+ assert_nil obj.attr
187
199
  assert_equal :to_ary, SubObject::SubArray::TO_SOURCE_METHOD
188
200
  assert_equal :itself, SubObject::TO_SOURCE_METHOD
189
201
  assert_raises(TypeError){ SubObject::SubArray.new ary, -3, :a }
@@ -205,6 +217,16 @@ class TestUnitSubObject < MiniTest::Test
205
217
  refute obj.respond_to?(:naiyo)
206
218
  assert_raises(NoMethodError){ obj.push 5 }
207
219
  assert_raises(NoMethodError){ obj.keep_if{} }
220
+
221
+ # Tests of attr
222
+ ary = [?a, ?b]
223
+ obj = SubObject::SubArray.new ary, -2, 1, attr: 5
224
+ assert_equal 5, obj.attr
225
+ hs = Hash[{ try: 67 }]
226
+ obj.attr = hs
227
+ assert_equal hs, obj.attr
228
+ obj.attr[:try] = 89
229
+ assert_equal 89, obj.attr[:try]
208
230
  end
209
231
 
210
232
  end # class TestUnitSubObject < MiniTest::Test
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sub_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masa Sakano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-07 00:00:00.000000000 Z
11
+ date: 2019-11-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Class SubObject that is the parent class for Ruby SubString and SubArray
14
14
  classes and alike, providing the base interface. This and child classes use negligible