epitools 0.5.36 → 0.5.37

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
  SHA1:
3
- metadata.gz: 62218ee364081707cdf868454642a359f73863c2
4
- data.tar.gz: 61fdb3c5bd004f72a9d1c8a3f769d8d325226867
3
+ metadata.gz: 74b5a665bc66555050576a5aa863b79017d10e90
4
+ data.tar.gz: a860badfc15c9f1f44f7d8db7aa4f47d2ef32bd4
5
5
  SHA512:
6
- metadata.gz: e7941b58505310ee7212e344ff45a890455b07354a2a934b589863e4b079b8b66d6369883d11d44978268e84bdb5032d4cfdc20e4161155e45dffcedc4c0aac1
7
- data.tar.gz: 9dcea6e9c715edf1c33d22a0f5afa84a3dde31a07bc9b5bbee7023ad6c97009c9ec77f27f6bb7d82169fbafd452c95363f173d5d237af507977f7dddcb21e652
6
+ metadata.gz: 1d19c2fd984f89485d8a00f7c2f8c5fb0cdeff916b1bf7fa8ea4a5922c447258a56ea21b610ae20e6c5e0b27d5e4679a4d9617b7263d9dbe1b36eaefff4a8f8e
7
+ data.tar.gz: db684ad10202d61c32167346cf6e3032316041308a0914bd3be5ac5b3ef535a687362966be703778f573686180c526ea3d4525957b9042669bb1cbd9d497e888
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.36
1
+ 0.5.37
@@ -5,6 +5,7 @@ require 'epitools'
5
5
  require 'epitools/core_ext/object'
6
6
  require 'epitools/core_ext/string'
7
7
  require 'epitools/core_ext/array'
8
+ require 'epitools/core_ext/file'
8
9
  require 'epitools/core_ext/enumerable'
9
10
  require 'epitools/core_ext/hash'
10
11
  require 'epitools/core_ext/numbers'
@@ -0,0 +1,102 @@
1
+ require 'epitools/minimal'
2
+
3
+ #
4
+ # Beginning of File reached! (Raised when reading a file backwards.)
5
+ #
6
+ class BOFError < Exception; end
7
+
8
+ class File
9
+
10
+ #
11
+ # A much faster `reverse_each` implementation.
12
+ #
13
+ def reverse_each(&block)
14
+ return to_enum(:reverse_each) unless block_given?
15
+
16
+ seek_end
17
+ reverse_each_from_current_pos(&block)
18
+ end
19
+
20
+ #
21
+ # Read the previous +length+ bytes. After the read, +pos+ will be at the beginning of the region that you just read.
22
+ #
23
+ def read_backwards(length)
24
+ old_pos = pos
25
+
26
+ if length > pos
27
+ seek(0)
28
+ else
29
+ seek(-length, IO::SEEK_CUR)
30
+ end
31
+
32
+ new_pos = pos
33
+ data = read(old_pos - new_pos)
34
+ seek(new_pos)
35
+
36
+ data
37
+ end
38
+
39
+ #
40
+ # Read each line of file backwards (from the current position.)
41
+ #
42
+ def reverse_each_from_current_pos
43
+ return to_enum(:reverse_each_from_current_pos) unless block_given?
44
+
45
+ fragment = readline rescue ""
46
+
47
+ loop do
48
+ data = read_backwards(4096) + fragment
49
+ loc = data.size-1
50
+
51
+ # NOTE: `rindex(str, loc)` includes the character at `loc`
52
+ while index = data.rindex("\n", loc-1)
53
+ line = data[index+1..loc]
54
+ yield line
55
+ loc = index
56
+ end
57
+
58
+ fragment = data[0..loc]
59
+
60
+ break if pos == 0 # we're done reading!
61
+ end
62
+
63
+ yield fragment
64
+ end
65
+
66
+ #
67
+ # Seek to `EOF`
68
+ #
69
+ def seek_end
70
+ seek(0, IO::SEEK_END)
71
+ end
72
+
73
+ #
74
+ # Read the previous line (leaving `pos` at the beginning of the string that was read.)
75
+ #
76
+ def reverse_readline
77
+ raise BOFError.new("beginning of file reached") if pos == 0
78
+
79
+ seek_backwards_to("\n", 512, -2)
80
+ new_pos = pos
81
+ data = readline
82
+ seek(new_pos)
83
+ data
84
+ end
85
+
86
+ #
87
+ # Scan backwards in the file until `string` is found, and set the IO's +pos+ to the first character after the matched string.
88
+ #
89
+ def seek_backwards_to(string, blocksize=512, rindex_end=-1)
90
+ loop do
91
+ data = read_backwards(blocksize)
92
+
93
+ if index = data.rindex(string, rindex_end)
94
+ seek(index+string.size, IO::SEEK_CUR)
95
+ break
96
+ elsif pos == 0
97
+ break
98
+ end
99
+ end
100
+ end
101
+
102
+ end
@@ -178,6 +178,15 @@ class Range
178
178
  Kernel.rand(self)
179
179
  end
180
180
 
181
+ #
182
+ # The middle element of this range.
183
+ #
184
+ def middle
185
+ (min + max) / 2
186
+ end
187
+
188
+
189
+
181
190
  end
182
191
 
183
192
 
@@ -268,16 +268,18 @@ class String
268
268
 
269
269
  # `true` if this string starts with the substring
270
270
  #
271
- def startswith(substring)
271
+ def startswith?(substring)
272
272
  self[0...substring.size] == substring
273
273
  end
274
+ alias_method :startswith, :startswith?
274
275
 
275
276
  #
276
277
  # `true` if this string ends with the substring
277
278
  #
278
- def endswith(substring)
279
+ def endswith?(substring)
279
280
  self[-substring.size..-1] == substring
280
281
  end
282
+ alias_method :endswith, :endswith?
281
283
 
282
284
  #
283
285
  # Parse this string as JSON
@@ -754,4 +754,16 @@ describe "to_hms and from_hms" do
754
754
  60.to_hms.from_hms.should == 60
755
755
  "1:20:33".from_hms.to_hms.should == "01:20:33"
756
756
  "5:01:20:33".from_hms.to_hms.should == "05:01:20:33"
757
+ end
758
+
759
+
760
+ describe File do
761
+
762
+ it "reverse_eaches" do
763
+ tmp = Path.tmp
764
+ tmp << "hi\nthere\neveryone!\n"
765
+ f = open(tmp)
766
+ f.reverse_each.to_a.should == ["everyone!\n", "there\n", "hi\n"]
767
+ end
768
+
757
769
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epitools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.36
4
+ version: 0.5.37
5
5
  platform: ruby
6
6
  authors:
7
7
  - epitron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-13 00:00:00.000000000 Z
11
+ date: 2013-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description: Miscellaneous utility libraries to make my life easier.
@@ -33,9 +33,9 @@ extra_rdoc_files:
33
33
  - README.rdoc
34
34
  - TODO
35
35
  files:
36
- - ".document"
37
- - ".gemspec"
38
- - ".gitignore"
36
+ - .document
37
+ - .gemspec
38
+ - .gitignore
39
39
  - Guardfile
40
40
  - LICENSE
41
41
  - README.rdoc
@@ -52,6 +52,7 @@ files:
52
52
  - lib/epitools/core_ext.rb
53
53
  - lib/epitools/core_ext/array.rb
54
54
  - lib/epitools/core_ext/enumerable.rb
55
+ - lib/epitools/core_ext/file.rb
55
56
  - lib/epitools/core_ext/hash.rb
56
57
  - lib/epitools/core_ext/matrix.rb
57
58
  - lib/epitools/core_ext/misc.rb
@@ -113,17 +114,17 @@ require_paths:
113
114
  - lib
114
115
  required_ruby_version: !ruby/object:Gem::Requirement
115
116
  requirements:
116
- - - ">="
117
+ - - '>='
117
118
  - !ruby/object:Gem::Version
118
119
  version: '0'
119
120
  required_rubygems_version: !ruby/object:Gem::Requirement
120
121
  requirements:
121
- - - ">="
122
+ - - '>='
122
123
  - !ruby/object:Gem::Version
123
124
  version: '0'
124
125
  requirements: []
125
126
  rubyforge_project:
126
- rubygems_version: 2.0.3
127
+ rubygems_version: 2.1.11
127
128
  signing_key:
128
129
  specification_version: 3
129
130
  summary: Not utils... METILS!