structure 0.13.1 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +3 -0
- data/CHANGELOG.md +23 -13
- data/Gemfile +2 -1
- data/README.md +16 -63
- data/lib/structure/version.rb +2 -2
- data/lib/structure.rb +31 -48
- data/structure.gemspec +3 -3
- data/test/structure_test.rb +72 -77
- metadata +26 -45
- data/.rvmrc +0 -1
- data/test/models.rb +0 -8
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,26 +1,36 @@
|
|
1
|
-
#
|
1
|
+
# CHANGELOG
|
2
2
|
|
3
|
-
|
4
|
-
*
|
3
|
+
## 0.14.1
|
4
|
+
* rename .attribute back to .key
|
5
|
+
* shorten .embeds_many and .embeds_one to .many and .one
|
6
|
+
* remove presence methods
|
7
|
+
* add options to .many
|
5
8
|
|
6
|
-
|
9
|
+
## 0.13.1
|
7
10
|
|
8
|
-
*
|
11
|
+
* remove static module
|
12
|
+
* rename .key to .attribute
|
9
13
|
|
10
|
-
# 0.
|
14
|
+
# 0.12.1
|
11
15
|
|
12
|
-
*
|
16
|
+
* add static module
|
13
17
|
|
14
|
-
# 0.
|
18
|
+
# 0.11.1
|
15
19
|
|
16
|
-
*
|
17
|
-
|
20
|
+
* .key now emulates DataMapper.property
|
21
|
+
|
22
|
+
# 0.10.1
|
23
|
+
|
24
|
+
* rename .has_one and .has_many to .embeds_one and .embeds_many to make room
|
25
|
+
for associations
|
18
26
|
|
19
27
|
# 0.9
|
20
28
|
|
21
|
-
*
|
29
|
+
* add presence method
|
22
30
|
|
23
31
|
# 0.8
|
24
32
|
|
25
|
-
*
|
26
|
-
*
|
33
|
+
* make JSON patch compatible with Active Support
|
34
|
+
* remove URI from list of types
|
35
|
+
|
36
|
+
The rest is history.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,75 +1,28 @@
|
|
1
1
|
# Structure
|
2
2
|
|
3
|
-
|
3
|
+
Structure is a Struct-like key/value container.
|
4
4
|
|
5
|
-
|
5
|
+
[![travis](https://secure.travis-ci.org/papercavalier/structure.png)](http://travis-ci.org/papercavalier/structure)
|
6
6
|
|
7
7
|
## Usage
|
8
8
|
|
9
|
-
Set up
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
require 'structure'
|
13
|
-
|
14
|
-
class Book
|
15
|
-
include Structure
|
16
|
-
|
17
|
-
attribute :title
|
18
|
-
attribute :binding, :default => "Hardcover"
|
19
|
-
attribute :year_published, Integer
|
20
|
-
embeds_many :authors
|
21
|
-
end
|
22
|
-
|
23
|
-
class Author
|
24
|
-
include Structure
|
25
|
-
|
26
|
-
attribute :name
|
27
|
-
attribute :role
|
28
|
-
end
|
29
|
-
```
|
30
|
-
|
31
|
-
Create some objects.
|
32
|
-
|
33
|
-
```ruby
|
34
|
-
book = Book.new :title => "A Thousand Plateaus"
|
35
|
-
author = Author.new :name => "Gilles Deleuze"
|
36
|
-
book.authors << author
|
37
|
-
```
|
38
|
-
|
39
|
-
Attributes in structures are typecasted.
|
40
|
-
|
41
|
-
```ruby
|
42
|
-
book.year_published = "1985"
|
43
|
-
puts book.year_published
|
44
|
-
=> 1985
|
45
|
-
```
|
46
|
-
|
47
|
-
Translate to JSON and back into Ruby.
|
48
|
-
|
49
|
-
```ruby
|
50
|
-
json = book.to_json
|
51
|
-
puts json
|
52
|
-
=> {"json_class":"Book","title":"A Thousand Plateaus","binding":"Hardcover,"year_published":1985,"authors":[{"json_class":"Author","name":"Gilles Deleuze","role":null}]}
|
9
|
+
Set up a model:
|
53
10
|
|
54
|
-
|
55
|
-
puts book.authors.first.name
|
56
|
-
=> "Gilles Deleuze"
|
57
|
-
```
|
11
|
+
require 'structure'
|
58
12
|
|
59
|
-
|
13
|
+
class Person < Structure
|
14
|
+
key :name
|
15
|
+
many :friends
|
16
|
+
end
|
60
17
|
|
61
|
-
|
62
|
-
require 'active_model'
|
18
|
+
Do things with it:
|
63
19
|
|
64
|
-
|
65
|
-
|
20
|
+
person = Person.new
|
21
|
+
friend = Person.new
|
22
|
+
person.friends << friend
|
23
|
+
puts person.to_json
|
24
|
+
=> {"json_class":"Person","name":null,"friends":[{"json_class":"Person","name":null,"friends":[]}]}
|
66
25
|
|
67
|
-
|
68
|
-
end
|
26
|
+
Please see [the project page] [1] for more detailed info.
|
69
27
|
|
70
|
-
|
71
|
-
book.valid?
|
72
|
-
=> false
|
73
|
-
book.errors
|
74
|
-
=> {:title=>["can't be blank"]}
|
75
|
-
```
|
28
|
+
[1]: http://code.papercavalier.com/structure/
|
data/lib/structure/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = '0.
|
1
|
+
class Structure
|
2
|
+
VERSION = '0.14.1'
|
3
3
|
end
|
data/lib/structure.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
begin
|
2
|
-
|
2
|
+
JSON::JSON_LOADED
|
3
3
|
rescue NameError
|
4
4
|
require 'json'
|
5
5
|
end
|
@@ -10,35 +10,34 @@ unless defined? Boolean
|
|
10
10
|
[TrueClass, FalseClass].each { |klass| klass.send :include, Boolean }
|
11
11
|
end
|
12
12
|
|
13
|
-
# Structure
|
13
|
+
# = Structure
|
14
14
|
#
|
15
|
-
#
|
16
|
-
# include Structure
|
15
|
+
# Structure is a Struct-like key/value container.
|
17
16
|
#
|
18
|
-
#
|
19
|
-
#
|
17
|
+
# class Person < Structure
|
18
|
+
# key :name
|
19
|
+
# key :age, Integer
|
20
20
|
# end
|
21
21
|
#
|
22
22
|
# person = Person.new(:name => "John")
|
23
23
|
# person.name
|
24
24
|
# => "John"
|
25
25
|
#
|
26
|
-
|
26
|
+
class Structure
|
27
27
|
include Enumerable
|
28
28
|
|
29
29
|
# Structure supports the following types.
|
30
30
|
TYPES = [Array, Boolean, Float, Hash, Integer, String, Structure]
|
31
31
|
|
32
|
-
|
33
|
-
# Defines an attribute that represents an array of objects
|
34
|
-
|
35
|
-
|
36
|
-
attribute key, Array, :default => []
|
32
|
+
class << self
|
33
|
+
# Defines an attribute that represents an array of objects.
|
34
|
+
def many(name, options = {})
|
35
|
+
key name, Array, { :default => [] }.merge(options)
|
37
36
|
end
|
38
37
|
|
39
38
|
# Defines an attribute that represents another structure.
|
40
|
-
def
|
41
|
-
|
39
|
+
def one(name)
|
40
|
+
key name, Structure
|
42
41
|
end
|
43
42
|
|
44
43
|
# Builds a structure out of its JSON representation.
|
@@ -49,33 +48,38 @@ module Structure
|
|
49
48
|
|
50
49
|
# Defines an attribute.
|
51
50
|
#
|
52
|
-
# Takes a
|
51
|
+
# Takes a name, an optional type, and an optional hash of options.
|
53
52
|
#
|
54
53
|
# The type can be +Array+, +Boolean+, +Float+, +Hash+, +Integer+, +String+,
|
55
|
-
#
|
54
|
+
# a +Structure+, or a subclass thereof. If none is specified, this defaults
|
55
|
+
# to +String+.
|
56
56
|
#
|
57
57
|
# Available options are:
|
58
58
|
#
|
59
59
|
# * +:default+, which sets the default value for the attribute.
|
60
|
-
def
|
61
|
-
|
60
|
+
def key(name, *args)
|
61
|
+
name = name.to_sym
|
62
62
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
63
63
|
type = args.shift || String
|
64
64
|
default = options[:default]
|
65
65
|
|
66
|
-
if method_defined?
|
67
|
-
raise NameError, "#{
|
66
|
+
if method_defined? name
|
67
|
+
raise NameError, "#{name} is already defined"
|
68
68
|
end
|
69
69
|
|
70
|
-
if
|
71
|
-
|
70
|
+
if (type.ancestors & TYPES).empty?
|
71
|
+
raise TypeError, "#{type} is not a valid type"
|
72
|
+
end
|
73
|
+
|
74
|
+
if default.nil? || default.is_a?(type)
|
75
|
+
default_attributes[name] = default
|
72
76
|
else
|
73
77
|
msg = "#{default} is not a#{'n' if type.to_s.match(/^[AI]/)} #{type}"
|
74
78
|
raise TypeError, msg
|
75
79
|
end
|
76
80
|
|
77
81
|
module_eval do
|
78
|
-
#
|
82
|
+
# Typecast value based on type.
|
79
83
|
typecast =
|
80
84
|
if type == Boolean
|
81
85
|
lambda do |value|
|
@@ -91,8 +95,6 @@ module Structure
|
|
91
95
|
end
|
92
96
|
end
|
93
97
|
elsif [Hash, Structure].include? type
|
94
|
-
# Don't bother with typecasting attributes of type +Hash+ or
|
95
|
-
# +Structure+.
|
96
98
|
lambda do |value|
|
97
99
|
unless value.is_a? type
|
98
100
|
raise TypeError, "#{value} is not a #{type}"
|
@@ -104,15 +106,10 @@ module Structure
|
|
104
106
|
end
|
105
107
|
|
106
108
|
# Define attribute accessors.
|
107
|
-
define_method(
|
109
|
+
define_method(name) { @attributes[name] }
|
108
110
|
|
109
|
-
define_method("#{
|
110
|
-
@attributes[
|
111
|
-
end
|
112
|
-
|
113
|
-
# Define a method to check for presence.
|
114
|
-
unless type == Array
|
115
|
-
define_method("#{key}?") { !!@attributes[key] }
|
111
|
+
define_method("#{name}=") do |value|
|
112
|
+
@attributes[name] = value.nil? ? nil : typecast.call(value)
|
116
113
|
end
|
117
114
|
end
|
118
115
|
end
|
@@ -123,10 +120,6 @@ module Structure
|
|
123
120
|
end
|
124
121
|
end
|
125
122
|
|
126
|
-
def self.included(base)
|
127
|
-
base.extend(ClassMethods)
|
128
|
-
end
|
129
|
-
|
130
123
|
# Creates a new structure.
|
131
124
|
#
|
132
125
|
# A hash, if provided, will seed its attributes.
|
@@ -140,7 +133,7 @@ module Structure
|
|
140
133
|
end
|
141
134
|
|
142
135
|
# A hash that stores the attributes of the structure.
|
143
|
-
|
136
|
+
attr :attributes
|
144
137
|
|
145
138
|
# Returns a Rails-friendly JSON representation of the structure.
|
146
139
|
def as_json(options = nil)
|
@@ -167,11 +160,6 @@ module Structure
|
|
167
160
|
@attributes.each { |value| block.call(value) }
|
168
161
|
end
|
169
162
|
|
170
|
-
# Returns an array populated with the attribute keys.
|
171
|
-
def keys
|
172
|
-
@attributes.keys
|
173
|
-
end
|
174
|
-
|
175
163
|
# Returns a JSON representation of the structure.
|
176
164
|
def to_json(*args)
|
177
165
|
klass = self.class.name
|
@@ -180,11 +168,6 @@ module Structure
|
|
180
168
|
to_json(*args)
|
181
169
|
end
|
182
170
|
|
183
|
-
# Returns an array populated with the attribute values.
|
184
|
-
def values
|
185
|
-
@attributes.values
|
186
|
-
end
|
187
|
-
|
188
171
|
# Compares this object with another object for equality. A Structure is equal
|
189
172
|
# to the other object when latter is of the same class and the two objects'
|
190
173
|
# attributes are the same.
|
data/structure.gemspec
CHANGED
@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "structure"
|
7
7
|
s.version = Structure::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["
|
9
|
+
s.authors = ["Hakan Ensari"]
|
10
10
|
s.email = ["code@papercavalier.com"]
|
11
11
|
s.homepage = "http://code.papercavalier.com/structure"
|
12
|
-
s.summary = "
|
13
|
-
s.description = "Structure
|
12
|
+
s.summary = "A Struct-like key/value container"
|
13
|
+
s.description = "Structure is a Struct-like key/value container."
|
14
14
|
|
15
15
|
s.rubyforge_project = "structure"
|
16
16
|
|
data/test/structure_test.rb
CHANGED
@@ -1,134 +1,129 @@
|
|
1
|
+
$:.push File.expand_path('../../lib', __FILE__)
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'bundler/setup'
|
3
|
-
require 'test/unit'
|
4
5
|
|
5
|
-
|
6
|
+
begin
|
7
|
+
require 'ruby-debug'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'structure'
|
12
|
+
require 'test/unit'
|
6
13
|
|
7
|
-
class
|
8
|
-
|
14
|
+
class Book < Structure
|
15
|
+
key :title
|
16
|
+
key :published, Boolean, :default => true
|
17
|
+
key :pages, Integer
|
18
|
+
end
|
9
19
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
embeds_many :children
|
20
|
+
class Person < Structure
|
21
|
+
key :name
|
22
|
+
one :partner
|
23
|
+
many :friends
|
15
24
|
end
|
16
25
|
|
17
26
|
class TestStructure < Test::Unit::TestCase
|
18
27
|
def test_enumeration
|
19
|
-
|
20
|
-
assert_respond_to(person, :map)
|
28
|
+
assert_respond_to Book.new, :map
|
21
29
|
end
|
22
30
|
|
23
|
-
def
|
24
|
-
|
25
|
-
assert_respond_to
|
26
|
-
assert_respond_to
|
27
|
-
assert_respond_to(person, :name?)
|
31
|
+
def test_accessors
|
32
|
+
book = Book.new
|
33
|
+
assert_respond_to book, :title
|
34
|
+
assert_respond_to book, :title=
|
28
35
|
end
|
29
36
|
|
30
|
-
def
|
31
|
-
assert_raise(NameError) {
|
32
|
-
assert_raise(TypeError) {
|
33
|
-
assert_raise(TypeError) {
|
37
|
+
def test_key_errors
|
38
|
+
assert_raise(NameError) { Book.key :class }
|
39
|
+
assert_raise(TypeError) { Book.key :foo, Object }
|
40
|
+
assert_raise(TypeError) { Book.key :foo, :default => 1 }
|
34
41
|
end
|
35
42
|
|
36
43
|
def test_default_attributes
|
37
|
-
|
44
|
+
exp = { :title => nil,
|
45
|
+
:published => true,
|
46
|
+
:pages => nil }
|
47
|
+
assert_equal exp, Book.default_attributes
|
38
48
|
end
|
39
49
|
|
40
50
|
def test_initialization
|
41
|
-
|
42
|
-
assert_equal
|
43
|
-
assert_equal
|
51
|
+
book = Book.new(:title => 'Foo', :pages => 100)
|
52
|
+
assert_equal 'Foo', book.title
|
53
|
+
assert_equal 100, book.pages
|
44
54
|
end
|
45
55
|
|
46
56
|
def test_typecasting
|
47
|
-
|
57
|
+
book = Book.new
|
48
58
|
|
49
|
-
|
50
|
-
assert_equal
|
59
|
+
book.pages = "100"
|
60
|
+
assert_equal 100, book.pages
|
51
61
|
|
52
|
-
|
53
|
-
assert_nil
|
54
|
-
end
|
62
|
+
book.pages = nil
|
63
|
+
assert_nil book.pages
|
55
64
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
person.married = nil
|
60
|
-
assert(!person.married?)
|
61
|
-
|
62
|
-
person.married = false
|
63
|
-
assert(!person.married?)
|
64
|
-
|
65
|
-
person.married = true
|
66
|
-
assert(person.married?)
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_default_type
|
70
|
-
person = Person.new
|
71
|
-
person.name = 1
|
72
|
-
assert(person.name.is_a? String)
|
65
|
+
book.title = 1
|
66
|
+
book.title = '1'
|
73
67
|
end
|
74
68
|
|
75
69
|
def test_boolean_typecasting
|
76
|
-
|
70
|
+
book = Book.new
|
77
71
|
|
78
|
-
|
79
|
-
assert
|
72
|
+
book.published = 'false'
|
73
|
+
assert book.published == false
|
80
74
|
|
81
|
-
|
82
|
-
assert
|
75
|
+
book.published = 'FALSE'
|
76
|
+
assert book.published == false
|
83
77
|
|
84
|
-
|
85
|
-
assert
|
78
|
+
book.published = '0'
|
79
|
+
assert book.published == false
|
86
80
|
|
87
|
-
|
88
|
-
assert
|
81
|
+
book.published = 'foo'
|
82
|
+
assert book.published == true
|
89
83
|
|
90
|
-
|
91
|
-
assert
|
84
|
+
book.published = 0
|
85
|
+
assert book.published == false
|
92
86
|
|
93
|
-
|
94
|
-
assert
|
87
|
+
book.published = 10
|
88
|
+
assert book.published == true
|
95
89
|
end
|
96
90
|
|
97
91
|
def test_defaults
|
98
|
-
|
99
|
-
assert_equal
|
100
|
-
assert_equal
|
101
|
-
assert_equal
|
102
|
-
assert_equal([], person.children)
|
92
|
+
assert_equal nil, Book.new.title
|
93
|
+
assert_equal true, Book.new.published
|
94
|
+
assert_equal nil, Person.new.partner
|
95
|
+
assert_equal [], Person.new.friends
|
103
96
|
end
|
104
97
|
|
105
98
|
def test_array
|
106
99
|
person = Person.new
|
107
|
-
|
108
|
-
person.
|
109
|
-
assert_equal
|
110
|
-
assert_equal
|
100
|
+
friend = Person.new
|
101
|
+
person.friends << person
|
102
|
+
assert_equal 1, person.friends.count
|
103
|
+
assert_equal 0, friend.friends.count
|
111
104
|
end
|
112
105
|
|
113
106
|
def test_json
|
114
|
-
|
115
|
-
json =
|
116
|
-
assert_equal
|
107
|
+
book = Book.new(:title => 'Foo')
|
108
|
+
json = book.to_json
|
109
|
+
assert_equal book, JSON.parse(json)
|
117
110
|
end
|
118
111
|
|
119
112
|
def test_json_with_nested_structures
|
120
113
|
person = Person.new
|
121
|
-
person.
|
114
|
+
person.friends << Person.new
|
115
|
+
person.partner = Person.new
|
122
116
|
json = person.to_json
|
123
|
-
assert
|
117
|
+
assert JSON.parse(json).friends.first.is_a? Person
|
118
|
+
assert JSON.parse(json).partner.is_a? Person
|
124
119
|
end
|
125
120
|
|
126
121
|
def test_json_with_active_support
|
127
122
|
require 'active_support/ordered_hash'
|
128
123
|
require 'active_support/json'
|
129
124
|
|
130
|
-
|
131
|
-
assert
|
132
|
-
assert
|
125
|
+
book = Book.new
|
126
|
+
assert book.as_json(:only => :title).has_key?(:title)
|
127
|
+
assert !book.as_json(:except => :title).has_key?(:title)
|
133
128
|
end
|
134
129
|
end
|
metadata
CHANGED
@@ -1,35 +1,24 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: structure
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 13
|
8
|
-
- 1
|
9
|
-
version: 0.13.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.14.1
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
12
|
-
-
|
7
|
+
authors:
|
8
|
+
- Hakan Ensari
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
date: 2011-07-26 00:00:00 +01:00
|
18
|
-
default_executable:
|
12
|
+
date: 2011-08-11 00:00:00.000000000Z
|
19
13
|
dependencies: []
|
20
|
-
|
21
|
-
|
22
|
-
email:
|
14
|
+
description: Structure is a Struct-like key/value container.
|
15
|
+
email:
|
23
16
|
- code@papercavalier.com
|
24
17
|
executables: []
|
25
|
-
|
26
18
|
extensions: []
|
27
|
-
|
28
19
|
extra_rdoc_files: []
|
29
|
-
|
30
|
-
files:
|
20
|
+
files:
|
31
21
|
- .gitignore
|
32
|
-
- .rvmrc
|
33
22
|
- .travis.yml
|
34
23
|
- CHANGELOG.md
|
35
24
|
- Gemfile
|
@@ -39,41 +28,33 @@ files:
|
|
39
28
|
- lib/structure.rb
|
40
29
|
- lib/structure/version.rb
|
41
30
|
- structure.gemspec
|
42
|
-
- test/models.rb
|
43
31
|
- test/structure_test.rb
|
44
|
-
has_rdoc: true
|
45
32
|
homepage: http://code.papercavalier.com/structure
|
46
33
|
licenses: []
|
47
|
-
|
48
34
|
post_install_message:
|
49
35
|
rdoc_options: []
|
50
|
-
|
51
|
-
require_paths:
|
36
|
+
require_paths:
|
52
37
|
- lib
|
53
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
39
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
segments:
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
segments:
|
60
45
|
- 0
|
61
|
-
|
62
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
hash: -3339689548870644271
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
48
|
none: false
|
64
|
-
requirements:
|
65
|
-
- -
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
|
68
|
-
- 0
|
69
|
-
version: "0"
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
70
53
|
requirements: []
|
71
|
-
|
72
54
|
rubyforge_project: structure
|
73
|
-
rubygems_version: 1.
|
55
|
+
rubygems_version: 1.8.6
|
74
56
|
signing_key:
|
75
57
|
specification_version: 3
|
76
|
-
summary:
|
77
|
-
test_files:
|
78
|
-
- test/models.rb
|
58
|
+
summary: A Struct-like key/value container
|
59
|
+
test_files:
|
79
60
|
- test/structure_test.rb
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm --create use 1.9.2@structure
|