magnetic 0.0.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/gemspec.rb +31 -0
- data/lib/magnetic.rb +21 -0
- data/lib/magnetic/binding_of_caller.rb +84 -0
- data/lib/magnetic/field.rb +227 -0
- data/lib/magnetic/interface.rb +99 -0
- data/lib/magnetic/rails.rb +32 -0
- data/lib/magnetic/rubyext.rb +30 -0
- data/magnetic-0.0.1.gem +0 -0
- metadata +90 -0
data/gemspec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
Gem::Specification::new do |spec|
|
7
|
+
$VERBOSE = nil
|
8
|
+
spec.name = lib
|
9
|
+
spec.version = version
|
10
|
+
spec.platform = Gem::Platform::RUBY
|
11
|
+
spec.summary = lib
|
12
|
+
|
13
|
+
spec.files = Dir::glob "**/**"
|
14
|
+
spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
|
15
|
+
|
16
|
+
spec.require_path = "lib"
|
17
|
+
spec.autorequire = lib
|
18
|
+
|
19
|
+
spec.has_rdoc = File::exist? "doc"
|
20
|
+
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
21
|
+
spec.add_dependency 'pervasives', '~> 1.0'
|
22
|
+
spec.add_dependency 'arrayfields', '~> 3.7'
|
23
|
+
spec.add_dependency 'attributes', '~> 3.3'
|
24
|
+
spec.add_dependency 'prototype', '~> 2.0'
|
25
|
+
|
26
|
+
spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
|
27
|
+
|
28
|
+
spec.author = "Ara T. Howard"
|
29
|
+
spec.email = "ara.t.howard@gmail.com"
|
30
|
+
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
31
|
+
end
|
data/lib/magnetic.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# built-in
|
3
|
+
#
|
4
|
+
require 'pathname'
|
5
|
+
require 'fileutils'
|
6
|
+
#
|
7
|
+
# gems
|
8
|
+
#
|
9
|
+
require 'rubygems'
|
10
|
+
require 'pervasives'
|
11
|
+
require 'arrayfields'
|
12
|
+
require 'attributes'
|
13
|
+
require 'prototype'
|
14
|
+
#
|
15
|
+
# magnetic
|
16
|
+
#
|
17
|
+
require 'magnetic/binding_of_caller'
|
18
|
+
require 'magnetic/rubyext'
|
19
|
+
require 'magnetic/field'
|
20
|
+
require 'magnetic/interface'
|
21
|
+
require 'magnetic/rails'
|
@@ -0,0 +1,84 @@
|
|
1
|
+
begin
|
2
|
+
require 'simplecc'
|
3
|
+
rescue LoadError
|
4
|
+
class Continuation # :nodoc: # for RDoc
|
5
|
+
end
|
6
|
+
def Continuation.create(*args, &block) # :nodoc:
|
7
|
+
cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
|
8
|
+
result ||= args
|
9
|
+
return *[cc, *result]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Binding; end # for RDoc
|
14
|
+
# This method returns the binding of the method that called your
|
15
|
+
# method. It will raise an Exception when you're not inside a method.
|
16
|
+
#
|
17
|
+
# It's used like this:
|
18
|
+
# def inc_counter(amount = 1)
|
19
|
+
# Binding.of_caller do |binding|
|
20
|
+
# # Create a lambda that will increase the variable 'counter'
|
21
|
+
# # in the caller of this method when called.
|
22
|
+
# inc = eval("lambda { |arg| counter += arg }", binding)
|
23
|
+
# # We can refer to amount from inside this block safely.
|
24
|
+
# inc.call(amount)
|
25
|
+
# end
|
26
|
+
# # No other statements can go here. Put them inside the block.
|
27
|
+
# end
|
28
|
+
# counter = 0
|
29
|
+
# 2.times { inc_counter }
|
30
|
+
# counter # => 2
|
31
|
+
#
|
32
|
+
# Binding.of_caller must be the last statement in the method.
|
33
|
+
# This means that you will have to put everything you want to
|
34
|
+
# do after the call to Binding.of_caller into the block of it.
|
35
|
+
# This should be no problem however, because Ruby has closures.
|
36
|
+
# If you don't do this an Exception will be raised. Because of
|
37
|
+
# the way that Binding.of_caller is implemented it has to be
|
38
|
+
# done this way.
|
39
|
+
def Binding.of_caller(&block)
|
40
|
+
old_critical = Thread.critical
|
41
|
+
Thread.critical = true
|
42
|
+
count = 0
|
43
|
+
cc, result, error, extra_data = Continuation.create(nil, nil)
|
44
|
+
error.call if error
|
45
|
+
|
46
|
+
tracer = lambda do |*args|
|
47
|
+
type, context, extra_data = args[0], args[4], args
|
48
|
+
if type == "return"
|
49
|
+
count += 1
|
50
|
+
# First this method and then calling one will return --
|
51
|
+
# the trace event of the second event gets the context
|
52
|
+
# of the method which called the method that called this
|
53
|
+
# method.
|
54
|
+
if count == 2
|
55
|
+
# It would be nice if we could restore the trace_func
|
56
|
+
# that was set before we swapped in our own one, but
|
57
|
+
# this is impossible without overloading set_trace_func
|
58
|
+
# in current Ruby.
|
59
|
+
set_trace_func(nil)
|
60
|
+
cc.call(eval("binding", context), nil, extra_data)
|
61
|
+
end
|
62
|
+
elsif type == "line" then
|
63
|
+
nil
|
64
|
+
elsif type == "c-return" and extra_data[3] == :set_trace_func then
|
65
|
+
nil
|
66
|
+
else
|
67
|
+
set_trace_func(nil)
|
68
|
+
error_msg = "Binding.of_caller used in non-method context or " +
|
69
|
+
"trailing statements of method using it aren't in the block."
|
70
|
+
cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
unless result
|
75
|
+
set_trace_func(tracer)
|
76
|
+
return nil
|
77
|
+
else
|
78
|
+
Thread.critical = old_critical
|
79
|
+
case block.arity
|
80
|
+
when 1 then yield(result)
|
81
|
+
else yield(result, extra_data)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module Magnetic
|
2
|
+
module Field
|
3
|
+
Base = Object.prototype do
|
4
|
+
name nil
|
5
|
+
owner nil
|
6
|
+
#controller nil
|
7
|
+
model nil
|
8
|
+
#interface nil
|
9
|
+
#records nil
|
10
|
+
value nil
|
11
|
+
#path nil
|
12
|
+
type :html
|
13
|
+
|
14
|
+
def __
|
15
|
+
@__ ||= Pervasives::Proxy.new(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
value.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
attribute('template_root'){ File.join RAILS_ROOT, 'app', 'views', 'magnetic' }
|
23
|
+
attribute('template_dir'){ File.join template_root, File.join(*owner.name.gsub(%r/^:+/,'').split(%r/::/)).downcase }
|
24
|
+
attribute('template_base'){ name }
|
25
|
+
#attribute('template_ext'){ type.to_s }
|
26
|
+
attribute('template_prefix'){ File.join(template_dir, template_base) }
|
27
|
+
attribute('template_inline'){ send "template_inline_#{ type }" }
|
28
|
+
attribute('template_text'){ nil }
|
29
|
+
attribute('template_map'){ { 'html' => 'rhtml', 'xml' => 'rxml' } }
|
30
|
+
|
31
|
+
#
|
32
|
+
# TODO - this needs to be thought out further
|
33
|
+
#
|
34
|
+
def render *argv
|
35
|
+
raise 'recursive render!' if defined?(@inside_render) and @inside_render
|
36
|
+
@inside_render = true
|
37
|
+
begin
|
38
|
+
field = self
|
39
|
+
|
40
|
+
type = argv.delete_first{|arg| String === arg or Symbol === arg } || self.type
|
41
|
+
type = type.to_s
|
42
|
+
|
43
|
+
options = argv.delete_first{|arg| Hash === arg} || {}
|
44
|
+
options.to_options!
|
45
|
+
|
46
|
+
msg = options.delete(:render) || :render_to_string
|
47
|
+
|
48
|
+
text = options[:text] || template_text rescue nil
|
49
|
+
inline = options[:inline] || template_inline rescue nil
|
50
|
+
|
51
|
+
unless text or inline
|
52
|
+
file = options[:file]
|
53
|
+
unless file
|
54
|
+
ext = (template_map[type] || type).gsub %r/^\.?/, '.'
|
55
|
+
options[:file] = template_prefix + ext
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
controller.clone.instance_eval do
|
60
|
+
@field = field
|
61
|
+
(options[:locals] ||= {}).update :field => @field
|
62
|
+
send msg, options
|
63
|
+
end
|
64
|
+
ensure
|
65
|
+
@inside_render = false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def configure options = {}, &block
|
70
|
+
options.to_options!
|
71
|
+
prototyping do
|
72
|
+
options.each do |k,v|
|
73
|
+
begin
|
74
|
+
__send__ "#{ k }=", v
|
75
|
+
rescue
|
76
|
+
__attribute__ k => v
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
prototyping &block
|
81
|
+
self
|
82
|
+
end
|
83
|
+
alias_method 'configured', 'configure'
|
84
|
+
|
85
|
+
def to_proc
|
86
|
+
@to_proc ||= lambda do |options|
|
87
|
+
options.to_options!
|
88
|
+
field = self
|
89
|
+
value = options[:value]
|
90
|
+
unless value.nil?
|
91
|
+
sc =
|
92
|
+
class << value
|
93
|
+
self
|
94
|
+
end
|
95
|
+
sc.module_eval do
|
96
|
+
define_method :field do
|
97
|
+
field.configure options
|
98
|
+
field
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def to_proc
|
107
|
+
@to_proc ||= lambda do |options|
|
108
|
+
field = self
|
109
|
+
field_options = options.to_options
|
110
|
+
value = options[:value]
|
111
|
+
raise ArgumentError, "no value in <#{ options.inspect }>" unless value
|
112
|
+
value.extend ConfiguredFieldMethod
|
113
|
+
value.field = field
|
114
|
+
value.field_options = field_options
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module ConfiguredFieldMethod
|
119
|
+
attr_writer 'field'
|
120
|
+
attr_writer 'field_options'
|
121
|
+
|
122
|
+
def field
|
123
|
+
@field_options.each do |k, v|
|
124
|
+
unless @field.respond_to? k
|
125
|
+
sc =
|
126
|
+
class << @field
|
127
|
+
self
|
128
|
+
end
|
129
|
+
sc.module_eval{ attribute k }
|
130
|
+
end
|
131
|
+
@field.send "#{ k }=", v
|
132
|
+
end
|
133
|
+
@field
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def === other
|
138
|
+
Base.class === other
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
### TODO try not to use array fields here
|
143
|
+
class Set < ::Array
|
144
|
+
include Fieldable
|
145
|
+
class << self
|
146
|
+
def [] *a, &b
|
147
|
+
a = super
|
148
|
+
ensure
|
149
|
+
a.fields = []
|
150
|
+
end
|
151
|
+
end
|
152
|
+
def initialize *a, &b
|
153
|
+
super
|
154
|
+
ensure
|
155
|
+
self.fields = []
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
module DSL
|
160
|
+
def fieldset
|
161
|
+
@fieldset ||= Field::Set[]
|
162
|
+
end
|
163
|
+
def field *argv, &block
|
164
|
+
name = argv.delete_first{|arg| String === arg or Symbol === arg }
|
165
|
+
base = argv.delete_first{|arg| Field::Base.class === arg}
|
166
|
+
configuring = argv.delete_first{|arg| ['configure', :configure, 'configuring', :configuring].include? arg}
|
167
|
+
options = argv.delete_first{|arg| Hash === arg}
|
168
|
+
|
169
|
+
name ||= base.name
|
170
|
+
raise ArgumentError, 'nameless field!' unless name
|
171
|
+
name = name.to_s
|
172
|
+
|
173
|
+
if options.nil? and base.nil? and block.nil?
|
174
|
+
field = field_for name
|
175
|
+
field.clone unless field.nil?
|
176
|
+
else
|
177
|
+
options ||= {}
|
178
|
+
options.to_options!
|
179
|
+
field =
|
180
|
+
if configuring
|
181
|
+
field_for name
|
182
|
+
else
|
183
|
+
base ||= Field::Base
|
184
|
+
field = base.clone
|
185
|
+
field.name = name
|
186
|
+
field.owner = self
|
187
|
+
field
|
188
|
+
end
|
189
|
+
|
190
|
+
field.configure options, &block
|
191
|
+
|
192
|
+
#p [ (field.owner.name rescue field.owner.class.name), field.name, (configuring ? :configuring : false), caller.first ]
|
193
|
+
|
194
|
+
unless configuring
|
195
|
+
raise ArgumentError, "duplicate field '#{ name }' in #{ fieldset[name].inspect }" if fieldset.has_key?(field.name)
|
196
|
+
fieldset[field.name] = field
|
197
|
+
end
|
198
|
+
|
199
|
+
field
|
200
|
+
end
|
201
|
+
end
|
202
|
+
def field_for name
|
203
|
+
fieldset[name.to_s]
|
204
|
+
end
|
205
|
+
def self.included other
|
206
|
+
super
|
207
|
+
ensure
|
208
|
+
other.extend self
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def self.field *argv, &block
|
214
|
+
name = argv.delete_first{|arg| String === arg or Symbol === arg }
|
215
|
+
base = argv.delete_first{|arg| Field::Base.class === arg}
|
216
|
+
configure = argv.delete_first{|arg| ['configure', :configure].include? arg}
|
217
|
+
options = argv.delete_first{|arg| Hash === arg}
|
218
|
+
options ||= {}
|
219
|
+
options.to_options!
|
220
|
+
base ||= Field::Base
|
221
|
+
field = base.clone
|
222
|
+
field.name = name
|
223
|
+
field.owner = self
|
224
|
+
field.configure options, &block
|
225
|
+
field
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Magnetic
|
2
|
+
class Path < ::String; end
|
3
|
+
def self.path(*a, &b) a.size == 0 ? Path : Path.new(*a, &b) end
|
4
|
+
|
5
|
+
class Interface
|
6
|
+
include Magnetic::Field::DSL
|
7
|
+
|
8
|
+
attribute 'records'
|
9
|
+
attribute 'mapping'
|
10
|
+
|
11
|
+
def initialize options = {}, &block
|
12
|
+
options.to_options!
|
13
|
+
records = options[:records]
|
14
|
+
controller = options[:controller]
|
15
|
+
@records = (( Array === records and ActiveRecord::Base === records[0] )) ? records : [records]
|
16
|
+
@records = [] if records.nil?
|
17
|
+
@controller = controller
|
18
|
+
@mapping = []
|
19
|
+
instance_eval &block if block
|
20
|
+
post_initialize
|
21
|
+
end
|
22
|
+
|
23
|
+
def map mapping
|
24
|
+
mapping.each do |key, value|
|
25
|
+
key = key.to_s
|
26
|
+
raise ArgumentError, 'empty key!' if key.empty?
|
27
|
+
raise ArgumentError, 'no value!' if value.nil?
|
28
|
+
@mapping << [key, value]
|
29
|
+
if Magnetic::Field::Base === value
|
30
|
+
field(value) unless field(value.name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def post_initialize
|
36
|
+
map!
|
37
|
+
end
|
38
|
+
|
39
|
+
def map!
|
40
|
+
@records.each{|record| map_record :record => record, :mapping => @mapping} unless @mapping.empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
def map_record options = {}
|
44
|
+
options.to_options!
|
45
|
+
|
46
|
+
record = options.delete :record
|
47
|
+
mapping = options.delete :mapping
|
48
|
+
route = options.delete :route
|
49
|
+
|
50
|
+
table_name = record.class.table_name
|
51
|
+
id = record.id
|
52
|
+
|
53
|
+
(( route ||= [] )) << "#{ table_name }[#{ id }]"
|
54
|
+
|
55
|
+
mapping.each do |path, block|
|
56
|
+
head, *tail = path.split '.'
|
57
|
+
m, head, array, *ignored = %r/^(.*?)(\[\*?\])?$/o.match(head).to_a
|
58
|
+
|
59
|
+
if array
|
60
|
+
subrecords = record.send head
|
61
|
+
subrecords = [subrecords] unless subrecords.class == Array
|
62
|
+
subpath = tail.join '.'
|
63
|
+
subblock = block
|
64
|
+
submapping = [[ subpath, subblock ]]
|
65
|
+
subrecords.each do |subrecord|
|
66
|
+
subroute = route.clone
|
67
|
+
map_record :record => subrecord, :mapping => submapping, :route => subroute
|
68
|
+
end
|
69
|
+
else
|
70
|
+
value = record.send head
|
71
|
+
path = Magnetic.path(( [route, head].join('.') ))
|
72
|
+
block.to_proc.call :path => path,
|
73
|
+
:value => value,
|
74
|
+
:model => record.class,
|
75
|
+
:table_name => table_name,
|
76
|
+
:column_name => head,
|
77
|
+
:record => record,
|
78
|
+
:interface => self,
|
79
|
+
:controller => @controller
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
module DSL
|
85
|
+
def interface *a, &b
|
86
|
+
if a.empty? and b.nil?
|
87
|
+
@interface
|
88
|
+
else
|
89
|
+
@interface = Interface.new :records => a.shift, :controller => self, &b
|
90
|
+
end
|
91
|
+
end
|
92
|
+
def self.included other
|
93
|
+
super
|
94
|
+
ensure
|
95
|
+
other.extend self
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
if defined? Rails or defined? RAILS
|
2
|
+
class ActiveRecord::Base
|
3
|
+
include Magnetic::Field::DSL
|
4
|
+
|
5
|
+
def self.field_for name
|
6
|
+
name = name.to_s
|
7
|
+
fieldset[name] or generate_default_field_for(name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.generate_default_field_for name
|
11
|
+
cname = name.to_s
|
12
|
+
m = self
|
13
|
+
raise ArgumentError, "no such column <#{ cname }>" unless columns_hash[cname]
|
14
|
+
field cname do
|
15
|
+
model m
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if defined? ActionController
|
21
|
+
class ActionController::Base
|
22
|
+
include Magnetic::Interface::DSL
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
unless defined? ApplicationController
|
27
|
+
class ApplicationController < ActionController::Base; end
|
28
|
+
end
|
29
|
+
class ApplicationController
|
30
|
+
include Magnetic::Interface::DSL
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Object
|
2
|
+
def higherself
|
3
|
+
Binding.of_caller{|binding| eval 'self', binding}
|
4
|
+
end
|
5
|
+
end
|
6
|
+
class Hash
|
7
|
+
unless instance_methods.include? 'to_options'
|
8
|
+
def to_options
|
9
|
+
keys.inject({}){|h,k| h.update k.to_s.to_sym => self[k]}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
unless instance_methods.include? 'to_options!'
|
13
|
+
def to_options!
|
14
|
+
replace to_options
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
class Array
|
19
|
+
def delete_first *argv, &block
|
20
|
+
match = block ? block : lambda{|arg| argv.first == arg}
|
21
|
+
at = nil
|
22
|
+
each_with_index do |element, index|
|
23
|
+
if match[element]
|
24
|
+
at = index
|
25
|
+
break
|
26
|
+
end
|
27
|
+
end
|
28
|
+
at ? delete_at(at) : nil
|
29
|
+
end
|
30
|
+
end
|
data/magnetic-0.0.1.gem
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: magnetic
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-06-04 00:00:00 -06:00
|
8
|
+
summary: magnetic
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ara.t.howard@gmail.com
|
12
|
+
homepage: http://codeforpeople.com/lib/ruby/magnetic/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: magnetic
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Ara T. Howard
|
31
|
+
files:
|
32
|
+
- gemspec.rb
|
33
|
+
- lib
|
34
|
+
- lib/magnetic
|
35
|
+
- lib/magnetic/binding_of_caller.rb
|
36
|
+
- lib/magnetic/field.rb
|
37
|
+
- lib/magnetic/interface.rb
|
38
|
+
- lib/magnetic/rails.rb
|
39
|
+
- lib/magnetic/rubyext.rb
|
40
|
+
- lib/magnetic.rb
|
41
|
+
- magnetic-0.0.1.gem
|
42
|
+
test_files: []
|
43
|
+
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
extra_rdoc_files: []
|
47
|
+
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
dependencies:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pervasives
|
57
|
+
version_requirement:
|
58
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "1.0"
|
63
|
+
version:
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: arrayfields
|
66
|
+
version_requirement:
|
67
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ~>
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "3.7"
|
72
|
+
version:
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: attributes
|
75
|
+
version_requirement:
|
76
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ~>
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "3.3"
|
81
|
+
version:
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: prototype
|
84
|
+
version_requirement:
|
85
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "2.0"
|
90
|
+
version:
|