storable 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.txt +4 -0
- data/README.rdoc +1 -1
- data/lib/proc_source.rb +215 -0
- data/lib/storable.rb +1 -1
- data/storable.gemspec +2 -1
- metadata +3 -2
data/CHANGES.txt
CHANGED
@@ -3,6 +3,10 @@ STORABLE, CHANGES
|
|
3
3
|
* TODO: Handle nested hashes and arrays.
|
4
4
|
* TODO: to_xml, see: http://codeforpeople.com/lib/ruby/xx/xx-2.0.0/README
|
5
5
|
|
6
|
+
#### 0.7.1 (2010-04-04) #############################
|
7
|
+
|
8
|
+
* FIXED: Missing proc_source.rb in gemspec.
|
9
|
+
|
6
10
|
#### 0.7.0 (2010-04-03) #############################
|
7
11
|
|
8
12
|
* FIXED: Default initialize method missed the last argument
|
data/README.rdoc
CHANGED
data/lib/proc_source.rb
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
#--
|
2
|
+
# Based on:
|
3
|
+
# http://github.com/imedo/background
|
4
|
+
#++
|
5
|
+
|
6
|
+
require 'stringio'
|
7
|
+
require 'irb/ruby-lex'
|
8
|
+
#SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
9
|
+
|
10
|
+
class ProcString < String
|
11
|
+
attr_accessor :file, :lines, :arity, :kind
|
12
|
+
def to_proc(kind="proc")
|
13
|
+
result = eval("#{kind} #{self}")
|
14
|
+
result.source = self
|
15
|
+
result
|
16
|
+
end
|
17
|
+
def to_lambda
|
18
|
+
to_proc "lamda"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class RubyToken::Token
|
23
|
+
|
24
|
+
# These EXPR_BEG tokens don't have associated end tags
|
25
|
+
FAKIES = [RubyToken::TkWHEN, RubyToken::TkELSIF, RubyToken::TkTHEN]
|
26
|
+
|
27
|
+
def open_tag?
|
28
|
+
return false if @name.nil? || get_props.nil?
|
29
|
+
a = (get_props[1] == RubyToken::EXPR_BEG) &&
|
30
|
+
self.class.to_s !~ /_MOD/ && # ignore onliner if, unless, etc...
|
31
|
+
!FAKIES.member?(self.class)
|
32
|
+
a
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_props
|
36
|
+
RubyToken::TkReading2Token[@name]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# Based heavily on code from http://github.com/imedo/background
|
42
|
+
# Big thanks to the imedo dev team!
|
43
|
+
#
|
44
|
+
module ProcSource
|
45
|
+
|
46
|
+
def self.find(filename, start_line=0, block_only=true)
|
47
|
+
lines, lexer = nil, nil
|
48
|
+
retried = 0
|
49
|
+
loop do
|
50
|
+
lines = get_lines(filename, start_line)
|
51
|
+
#p [start_line, lines[0]]
|
52
|
+
if !line_has_open?(lines.join) && start_line >= 0
|
53
|
+
start_line -= 1 and retried +=1 and redo
|
54
|
+
end
|
55
|
+
lexer = RubyLex.new
|
56
|
+
lexer.set_input(StringIO.new(lines.join))
|
57
|
+
break
|
58
|
+
end
|
59
|
+
stoken, etoken, nesting = nil, nil, 0
|
60
|
+
while token = lexer.token
|
61
|
+
n = token.instance_variable_get(:@name)
|
62
|
+
|
63
|
+
if RubyToken::TkIDENTIFIER === token
|
64
|
+
#nothing
|
65
|
+
elsif token.open_tag? || RubyToken::TkfLBRACE === token
|
66
|
+
nesting += 1
|
67
|
+
stoken = token if nesting == 1
|
68
|
+
elsif RubyToken::TkEND === token || RubyToken::TkRBRACE === token
|
69
|
+
if nesting == 1
|
70
|
+
etoken = token
|
71
|
+
break
|
72
|
+
end
|
73
|
+
nesting -= 1
|
74
|
+
elsif RubyToken::TkBITOR === token && stoken
|
75
|
+
#nothing
|
76
|
+
elsif RubyToken::TkNL === token && stoken && etoken
|
77
|
+
break if nesting <= 0
|
78
|
+
else
|
79
|
+
#p token
|
80
|
+
end
|
81
|
+
end
|
82
|
+
# puts lines if etoken.nil?
|
83
|
+
lines = lines[stoken.line_no-1 .. etoken.line_no-1]
|
84
|
+
|
85
|
+
# Remove the crud before the block definition.
|
86
|
+
if block_only
|
87
|
+
spaces = lines.last.match(/^\s+/)[0] rescue ''
|
88
|
+
lines[0] = spaces << lines[0][stoken.char_no .. -1]
|
89
|
+
end
|
90
|
+
ps = ProcString.new lines.join
|
91
|
+
ps.file, ps.lines = filename, start_line .. start_line+etoken.line_no-1
|
92
|
+
|
93
|
+
ps
|
94
|
+
end
|
95
|
+
|
96
|
+
# A hack for Ruby 1.9, otherwise returns true.
|
97
|
+
#
|
98
|
+
# Ruby 1.9 returns an incorrect line number
|
99
|
+
# when a block is specified with do/end. It
|
100
|
+
# happens b/c the line number returned by
|
101
|
+
# Ruby 1.9 is based on the first line in the
|
102
|
+
# block which contains a token (i.e. not a
|
103
|
+
# new line or comment etc...).
|
104
|
+
#
|
105
|
+
# NOTE: This won't work in cases where the
|
106
|
+
# incorrect line also contains a "do".
|
107
|
+
#
|
108
|
+
def self.line_has_open?(str)
|
109
|
+
return true unless RUBY_VERSION >= '1.9'
|
110
|
+
lexer = RubyLex.new
|
111
|
+
lexer.set_input(StringIO.new(str))
|
112
|
+
success = false
|
113
|
+
while token = lexer.token
|
114
|
+
case token
|
115
|
+
when RubyToken::TkNL
|
116
|
+
break
|
117
|
+
when RubyToken::TkDO
|
118
|
+
success = true
|
119
|
+
when RubyToken::TkCONSTANT
|
120
|
+
if token.instance_variable_get(:@name) == "Proc" &&
|
121
|
+
lexer.token.is_a?(RubyToken::TkDOT)
|
122
|
+
method = lexer.token
|
123
|
+
if method.is_a?(RubyToken::TkIDENTIFIER) &&
|
124
|
+
method.instance_variable_get(:@name) == "new"
|
125
|
+
success = true
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
success
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def self.get_lines(filename, start_line = 0)
|
135
|
+
case filename
|
136
|
+
when nil
|
137
|
+
nil
|
138
|
+
## NOTE: IRB AND EVAL LINES NOT TESTED
|
139
|
+
### special "(irb)" descriptor?
|
140
|
+
##when "(irb)"
|
141
|
+
## IRB.conf[:MAIN_CONTEXT].io.line(start_line .. -2)
|
142
|
+
### special "(eval...)" descriptor?
|
143
|
+
##when /^\(eval.+\)$/
|
144
|
+
## EVAL_LINES__[filename][start_line .. -2]
|
145
|
+
# regular file
|
146
|
+
else
|
147
|
+
# Ruby already parsed this file? (see disclaimer above)
|
148
|
+
if defined?(SCRIPT_LINES__) && SCRIPT_LINES__[filename]
|
149
|
+
SCRIPT_LINES__[filename][(start_line - 1) .. -1]
|
150
|
+
# If the file exists we're going to try reading it in
|
151
|
+
elsif File.exist?(filename)
|
152
|
+
begin
|
153
|
+
File.readlines(filename)[(start_line - 1) .. -1]
|
154
|
+
rescue
|
155
|
+
nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class Proc #:nodoc:
|
163
|
+
attr_reader :file, :line
|
164
|
+
attr_writer :source
|
165
|
+
|
166
|
+
def source_descriptor
|
167
|
+
unless @file && @line
|
168
|
+
if md = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+)(.+?)?>$/.match(inspect)
|
169
|
+
@file, @line = md.captures
|
170
|
+
end
|
171
|
+
end
|
172
|
+
[@file, @line.to_i]
|
173
|
+
end
|
174
|
+
|
175
|
+
def source
|
176
|
+
@source ||= ProcSource.find(*self.source_descriptor)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Create a Proc object from a string of Ruby code.
|
180
|
+
# It's assumed the string contains do; end or { }.
|
181
|
+
#
|
182
|
+
# Proc.from_string("do; 2+2; end")
|
183
|
+
#
|
184
|
+
def self.from_string(str)
|
185
|
+
eval "Proc.new #{str}"
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
if $0 == __FILE__
|
191
|
+
def store(&blk)
|
192
|
+
@blk = blk
|
193
|
+
end
|
194
|
+
|
195
|
+
store do |blk|
|
196
|
+
puts "Hello Rudy1"
|
197
|
+
end
|
198
|
+
|
199
|
+
a = Proc.new() { |a|
|
200
|
+
puts "Hello Rudy2"
|
201
|
+
}
|
202
|
+
|
203
|
+
b = Proc.new() do |b|
|
204
|
+
puts { "Hello Rudy3" } if true
|
205
|
+
end
|
206
|
+
|
207
|
+
puts @blk.inspect, @blk.source
|
208
|
+
puts [a.inspect, a.source]
|
209
|
+
puts b.inspect, b.source
|
210
|
+
|
211
|
+
proc = @blk.source.to_proc
|
212
|
+
proc.call(1)
|
213
|
+
end
|
214
|
+
|
215
|
+
|
data/lib/storable.rb
CHANGED
@@ -39,7 +39,7 @@ class Storable
|
|
39
39
|
require 'proc_source'
|
40
40
|
require 'storable/orderedhash' if USE_ORDERED_HASH
|
41
41
|
unless defined?(SUPPORTED_FORMATS) # We can assume all are defined
|
42
|
-
VERSION = "0.7.
|
42
|
+
VERSION = "0.7.1"
|
43
43
|
NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze
|
44
44
|
SUPPORTED_FORMATS = [:tsv, :csv, :yaml, :json, :s, :string].freeze
|
45
45
|
end
|
data/storable.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "storable"
|
3
3
|
s.rubyforge_project = "storable"
|
4
|
-
s.version = "0.7.
|
4
|
+
s.version = "0.7.1"
|
5
5
|
s.summary = "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|
@@ -28,6 +28,7 @@
|
|
28
28
|
LICENSE.txt
|
29
29
|
README.rdoc
|
30
30
|
Rakefile
|
31
|
+
lib/proc_source.rb
|
31
32
|
lib/storable.rb
|
32
33
|
lib/storable/orderedhash.rb
|
33
34
|
storable.gemspec
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: storable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-04-
|
12
|
+
date: 2010-04-04 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -27,6 +27,7 @@ files:
|
|
27
27
|
- LICENSE.txt
|
28
28
|
- README.rdoc
|
29
29
|
- Rakefile
|
30
|
+
- lib/proc_source.rb
|
30
31
|
- lib/storable.rb
|
31
32
|
- lib/storable/orderedhash.rb
|
32
33
|
- storable.gemspec
|