magnetic 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|