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.
@@ -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
@@ -1,4 +1,4 @@
1
- = Storable - v0.6
1
+ = Storable - v0.7
2
2
 
3
3
  Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)
4
4
 
@@ -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
+
@@ -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.0"
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
@@ -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.0"
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.0
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-03 00:00:00 -04:00
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