chars 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/.yardopts CHANGED
@@ -1 +1 @@
1
- --markup markdown --title 'Chars Documentation' --protected --files ChangeLog.md,LICENSE.txt
1
+ --markup markdown --title 'Chars Documentation' --protected --quiet --files ChangeLog.md,LICENSE.txt
@@ -1,3 +1,12 @@
1
+ ### 0.2.1 / 2011-06-22
2
+
3
+ * Added {Chars::CharSet.[]}
4
+ * Added {Chars::CharSet#<<}.
5
+ * Added {Chars::CharSet#byte_to_char}.
6
+ * Added {Chars::CharSet#char_to_byte}.
7
+ * Added a cache of characters of the bytes within {Chars::CharSet}.
8
+ * Use `String#each_char` to distinguish Unicode from ASCII.
9
+
1
10
  ### 0.2.0 / 2010-10-27
2
11
 
3
12
  * Make sure all enumerable methods in {Chars::CharSet} return an
data/README.md CHANGED
@@ -83,6 +83,10 @@ set of space characters:
83
83
  Chars.space.random_string(5..10)
84
84
  # => "\r\v\n\t\n\f"
85
85
 
86
+ ## Requirements
87
+
88
+ * [ruby](http://www.ruby-lang.org/) >= 1.8.7
89
+
86
90
  ## Install
87
91
 
88
92
  $ sudo gem install chars
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
 
4
4
  begin
5
- gem 'ore-tasks', '~> 0.1.2'
5
+ gem 'ore-tasks', '~> 0.4'
6
6
  require 'ore/tasks'
7
7
 
8
8
  Ore::Tasks.new
@@ -12,7 +12,7 @@ rescue LoadError => e
12
12
  end
13
13
 
14
14
  begin
15
- gem 'rspec', '~> 2.0.0'
15
+ gem 'rspec', '~> 2.4'
16
16
  require 'rspec/core/rake_task'
17
17
 
18
18
  RSpec::Core::RakeTask.new
@@ -21,6 +21,7 @@ rescue LoadError => e
21
21
  abort "Please run `gem install rspec` to install RSpec."
22
22
  end
23
23
  end
24
+ task :test => :spec
24
25
  task :default => :spec
25
26
 
26
27
  begin
@@ -1,10 +1,127 @@
1
- # -*- encoding: utf-8 -*-
1
+ # encoding: utf-8
2
2
 
3
- begin
4
- Ore::Specification.new do |gemspec|
5
- # custom logic here
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gemspec|
6
+ files = if File.directory?('.git')
7
+ `git ls-files`.split($/)
8
+ elsif File.directory?('.hg')
9
+ `hg manifest`.split($/)
10
+ elsif File.directory?('.svn')
11
+ `svn ls -R`.split($/).select { |path| File.file?(path) }
12
+ else
13
+ Dir['{**/}{.*,*}'].select { |path| File.file?(path) }
14
+ end
15
+
16
+ filter_files = lambda { |paths|
17
+ case paths
18
+ when Array
19
+ (files & paths)
20
+ when String
21
+ (files & Dir[paths])
22
+ end
23
+ }
24
+
25
+ version = {
26
+ :file => 'lib/chars/version.rb',
27
+ :constant => 'Chars::VERSION'
28
+ }
29
+
30
+ defaults = {
31
+ 'name' => File.basename(File.dirname(__FILE__)),
32
+ 'files' => files,
33
+ 'executables' => filter_files['bin/*'].map { |path| File.basename(path) },
34
+ 'test_files' => filter_files['{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'],
35
+ 'extra_doc_files' => filter_files['*.{txt,rdoc,md,markdown,tt,textile}'],
36
+ }
37
+
38
+ metadata = defaults.merge(YAML.load_file('gemspec.yml'))
39
+
40
+ gemspec.name = metadata.fetch('name',defaults[:name])
41
+ gemspec.version = if metadata['version']
42
+ metadata['version']
43
+ elsif File.file?(version[:file])
44
+ require File.join('.',version[:file])
45
+ eval(version[:constant])
46
+ end
47
+
48
+ gemspec.summary = metadata.fetch('summary',metadata['description'])
49
+ gemspec.description = metadata.fetch('description',metadata['summary'])
50
+
51
+ case metadata['license']
52
+ when Array
53
+ gemspec.licenses = metadata['license']
54
+ when String
55
+ gemspec.license = metadata['license']
56
+ end
57
+
58
+ case metadata['authors']
59
+ when Array
60
+ gemspec.authors = metadata['authors']
61
+ when String
62
+ gemspec.author = metadata['authors']
63
+ end
64
+
65
+ gemspec.email = metadata['email']
66
+ gemspec.homepage = metadata['homepage']
67
+
68
+ case metadata['require_paths']
69
+ when Array
70
+ gemspec.require_paths = metadata['require_paths']
71
+ when String
72
+ gemspec.require_path = metadata['require_paths']
73
+ end
74
+
75
+ gemspec.files = filter_files[metadata['files']]
76
+
77
+ gemspec.executables = metadata['executables']
78
+ gemspec.extensions = metadata['extensions']
79
+
80
+ if Gem::VERSION < '1.7.'
81
+ gemspec.default_executable = gemspec.executables.first
82
+ end
83
+
84
+ gemspec.test_files = filter_files[metadata['test_files']]
85
+
86
+ unless gemspec.files.include?('.document')
87
+ gemspec.extra_rdoc_files = metadata['extra_doc_files']
88
+ end
89
+
90
+ gemspec.post_install_message = metadata['post_install_message']
91
+ gemspec.requirements = metadata['requirements']
92
+
93
+ if gemspec.respond_to?(:required_ruby_version=)
94
+ gemspec.required_ruby_version = metadata['required_ruby_version']
95
+ end
96
+
97
+ if gemspec.respond_to?(:required_rubygems_version=)
98
+ gemspec.required_rubygems_version = metadata['required_ruby_version']
99
+ end
100
+
101
+ parse_versions = lambda { |versions|
102
+ case versions
103
+ when Array
104
+ versions.map { |v| v.to_s }
105
+ when String
106
+ versions.split(/,\s*/)
107
+ end
108
+ }
109
+
110
+ if metadata['dependencies']
111
+ metadata['dependencies'].each do |name,versions|
112
+ gemspec.add_dependency(name,parse_versions[versions])
113
+ end
114
+ end
115
+
116
+ if metadata['runtime_dependencies']
117
+ metadata['runtime_dependencies'].each do |name,versions|
118
+ gemspec.add_runtime_dependency(name,parse_versions[versions])
119
+ end
120
+ end
121
+
122
+ if metadata['development_dependencies']
123
+ metadata['development_dependencies'].each do |name,versions|
124
+ gemspec.add_development_dependency(name,parse_versions[versions])
125
+ end
6
126
  end
7
- rescue NameError
8
- STDERR.puts "The 'chars.gemspec' file requires Ore."
9
- STDERR.puts "Run `gem install ore` to install Ore."
10
127
  end
@@ -10,7 +10,9 @@ authors: Postmodern
10
10
  email: postmodern.mod3@gmail.com
11
11
  has_yard: true
12
12
 
13
+ required_ruby_version: ">= 1.8.7"
14
+
13
15
  development_dependencies:
14
- ore: ~> 0.2.0
15
- ore-tasks: ~> 0.1.2
16
- rspec: ~> 2.0.0
16
+ ore-tasks: ~> 0.4
17
+ rspec: ~> 2.4
18
+ yard: ~> 0.6.1
@@ -6,23 +6,67 @@ module Chars
6
6
  #
7
7
  # Creates a new CharSet object.
8
8
  #
9
- # @param [Array<String, Integer, Range>] chars
9
+ # @param [Array<String, Integer, Enumerable>] arguments
10
10
  # The chars for the CharSet.
11
11
  #
12
- def initialize(*chars)
12
+ def initialize(*arguments)
13
13
  super()
14
14
 
15
- merge_chars = lambda { |element|
16
- if element.kind_of?(String)
17
- element.each_byte(&merge_chars)
18
- elsif element.kind_of?(Integer)
19
- self << element
20
- elsif element.kind_of?(Enumerable)
21
- element.each(&merge_chars)
15
+ @chars = Hash.new { |hash,key| hash[key] = byte_to_char(key) }
16
+
17
+ arguments.each do |subset|
18
+ case subset
19
+ when String, Integer
20
+ self << subset
21
+ when Enumerable
22
+ subset.each { |char| self << char }
23
+ else
24
+ raise(ArgumentError,"arguments must be a String, Integer or Enumerable")
25
+ end
26
+ end
27
+ end
28
+
29
+ #
30
+ # Creates a new character set.
31
+ #
32
+ # @see #initialize
33
+ #
34
+ # @since 0.2.1
35
+ #
36
+ def self.[](*arguments)
37
+ new(*arguments)
38
+ end
39
+
40
+ #
41
+ # Adds a character to the set.
42
+ #
43
+ # @param [String, Integer] other
44
+ # The character(s) or byte to add.
45
+ #
46
+ # @return [CharSet]
47
+ # The modified character set.
48
+ #
49
+ # @raise [ArgumentError]
50
+ # The argument was not a {String} or {Integer}.
51
+ #
52
+ # @since 0.2.1
53
+ #
54
+ def <<(other)
55
+ case other
56
+ when String
57
+ other.each_char do |char|
58
+ byte = char_to_byte(char)
59
+
60
+ @chars[byte] = char
61
+ super(byte)
22
62
  end
23
- }
24
63
 
25
- merge_chars.call(chars)
64
+ return self
65
+ when Integer
66
+ super(other)
67
+ else
68
+ raise(ArgumentError,"can only append Strings and Integers")
69
+ end
26
70
  end
27
71
 
28
72
  alias include_byte? include?
@@ -42,8 +86,8 @@ module Chars
42
86
  # character set.
43
87
  #
44
88
  def include_char?(char)
45
- if char.respond_to?(:each_byte)
46
- char.each_byte.any? { |b| include?(b) }
89
+ unless char.empty?
90
+ @chars.has_value?(char) || include_byte?(char_to_byte(char))
47
91
  else
48
92
  false
49
93
  end
@@ -56,7 +100,7 @@ module Chars
56
100
  # All the characters within the character set.
57
101
  #
58
102
  def chars
59
- map { |b| b.chr }
103
+ map { |byte| @chars[byte] }
60
104
  end
61
105
 
62
106
  #
@@ -75,7 +119,7 @@ module Chars
75
119
  def each_char
76
120
  return enum_for(:each_char) unless block_given?
77
121
 
78
- each { |b| yield b.chr }
122
+ each { |byte| yield @chars[byte] }
79
123
  end
80
124
 
81
125
  #
@@ -92,7 +136,7 @@ module Chars
92
136
  # The selected characters from the character set.
93
137
  #
94
138
  def select_chars(&block)
95
- chars.select(&block)
139
+ each_char.select(&block)
96
140
  end
97
141
 
98
142
  #
@@ -109,7 +153,7 @@ module Chars
109
153
  # The mapped characters of the character set.
110
154
  #
111
155
  def map_chars(&block)
112
- chars.map(&block)
156
+ each_char.map(&block)
113
157
  end
114
158
 
115
159
  #
@@ -125,7 +169,7 @@ module Chars
125
169
  # A random char from the character set.
126
170
  #
127
171
  def random_char
128
- random_byte.chr
172
+ @chars[random_byte]
129
173
  end
130
174
 
131
175
  #
@@ -168,7 +212,7 @@ module Chars
168
212
  def each_random_char(n,&block)
169
213
  return enum_for(:each_random_char,n) unless block_given?
170
214
 
171
- each_random_byte(n) { |b| yield b.chr }
215
+ each_random_byte(n) { |byte| yield @chars[byte] }
172
216
  end
173
217
 
174
218
  #
@@ -215,7 +259,7 @@ module Chars
215
259
  # The randomly selected characters.
216
260
  #
217
261
  def random_chars(length)
218
- random_bytes(length).map { |b| b.chr }
262
+ random_bytes(length).map { |byte| @chars[byte] }
219
263
  end
220
264
 
221
265
  #
@@ -245,7 +289,7 @@ module Chars
245
289
  # The randomly selected non-repeating characters.
246
290
  #
247
291
  def random_distinct_chars(length)
248
- random_distinct_bytes(length).map { |b| b.chr }
292
+ random_distinct_bytes(length).map { |byte| @chars[byte] }
249
293
  end
250
294
 
251
295
  #
@@ -264,7 +308,6 @@ module Chars
264
308
  random_distinct_chars(length).join
265
309
  end
266
310
 
267
-
268
311
  #
269
312
  # Finds sub-strings within given data that are made of characters within
270
313
  # the character set.
@@ -284,7 +327,9 @@ module Chars
284
327
  # sub-strings themselves.
285
328
  #
286
329
  def strings_in(data,options={})
287
- min_length = (options[:length] || 4)
330
+ min_length = options.fetch(:length,4)
331
+
332
+ return found if data.length < min_length
288
333
 
289
334
  if options[:offsets]
290
335
  found = {}
@@ -298,15 +343,13 @@ module Chars
298
343
  }
299
344
  end
300
345
 
301
- return found if data.length < min_length
302
-
303
346
  index = 0
304
347
 
305
348
  while index <= (data.length - min_length)
306
- if self === data[index...(index + min_length)]
349
+ if self === data[index,min_length]
307
350
  sub_index = (index + min_length)
308
351
 
309
- while self.include_char?(data[sub_index..sub_index])
352
+ while self.include_char?(data[sub_index,1])
310
353
  sub_index += 1
311
354
  end
312
355
 
@@ -324,14 +367,16 @@ module Chars
324
367
  # Creates a new CharSet object by unioning the character set with
325
368
  # another character set.
326
369
  #
327
- # @param [CharSet, Array, Range] other_set
370
+ # @param [CharSet, Array, Range] set
328
371
  # The other character set to union with.
329
372
  #
330
373
  # @return [CharSet]
331
374
  # The unioned character sets.
332
375
  #
333
- def |(other_set)
334
- super(CharSet.new(other_set))
376
+ def |(set)
377
+ set = CharSet.new(set) unless set.kind_of?(CharSet)
378
+
379
+ return super(set)
335
380
  end
336
381
 
337
382
  alias + |
@@ -340,7 +385,7 @@ module Chars
340
385
  # Compares the bytes within a given string with the bytes of the
341
386
  # character set.
342
387
  #
343
- # @param [String] string
388
+ # @param [String, Enumerable] string
344
389
  # The string to compare with the character set.
345
390
  #
346
391
  # @return [Boolean]
@@ -351,9 +396,19 @@ module Chars
351
396
  # Chars.alpha === "hello"
352
397
  # # => true
353
398
  #
354
- def ===(string)
355
- if string.respond_to?(:each_byte)
356
- string.each_byte.all? { |b| include?(b) }
399
+ def ===(other)
400
+ case other
401
+ when String
402
+ other.each_char.all? { |char| include_char?(char) }
403
+ when Enumerable
404
+ other.all? do |element|
405
+ case element
406
+ when String
407
+ include_char?(element)
408
+ when Integer
409
+ include_byte?(element)
410
+ end
411
+ end
357
412
  else
358
413
  false
359
414
  end
@@ -368,19 +423,83 @@ module Chars
368
423
  # The inspected character set.
369
424
  #
370
425
  def inspect
371
- "#<#{self.class.name}: {" + map { |b|
372
- case b
426
+ "#<#{self.class.name}: {" + map { |byte|
427
+ case byte
373
428
  when (0x07..0x0d), (0x20..0x7e)
374
- b.chr.dump
429
+ @chars[byte].dump
375
430
  when 0x00
376
431
  # sly hack to make char-sets more friendly
377
432
  # to us C programmers
378
433
  '"\0"'
379
434
  else
380
- "0x%02x" % b
435
+ "0x%02x" % byte
381
436
  end
382
437
  }.join(', ') + "}>"
383
438
  end
384
439
 
440
+ protected
441
+
442
+ if RUBY_VERSION > '1.9.'
443
+ #
444
+ # Converts a byte to a character.
445
+ #
446
+ # @param [Integer] byte
447
+ # The byte to convert.
448
+ #
449
+ # @return [String]
450
+ # The character.
451
+ #
452
+ # @since 0.2.1
453
+ #
454
+ def byte_to_char(byte)
455
+ byte.chr(Encoding::UTF_8)
456
+ end
457
+
458
+ #
459
+ # Converts a character to a byte.
460
+ #
461
+ # @param [String] char
462
+ # The character to convert.
463
+ #
464
+ # @return [Integer]
465
+ # The byte.
466
+ #
467
+ # @since 0.2.1
468
+ #
469
+ def char_to_byte(char)
470
+ char.ord
471
+ end
472
+ else
473
+ #
474
+ # Converts a byte to a character.
475
+ #
476
+ # @param [Integer] byte
477
+ # The byte to convert.
478
+ #
479
+ # @return [String]
480
+ # The character.
481
+ #
482
+ # @since 0.2.1
483
+ #
484
+ def byte_to_char(byte)
485
+ byte.chr
486
+ end
487
+
488
+ #
489
+ # Converts a character to a byte.
490
+ #
491
+ # @param [String] char
492
+ # The character to convert.
493
+ #
494
+ # @return [Integer]
495
+ # The byte.
496
+ #
497
+ # @since 0.2.1
498
+ #
499
+ def char_to_byte(char)
500
+ char[0]
501
+ end
502
+ end
503
+
385
504
  end
386
505
  end