ascribe 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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +9 -0
- data/Rakefile +25 -0
- data/ascribe.gemspec +27 -0
- data/lib/ascribe/attribute.rb +36 -0
- data/lib/ascribe/attributes.rb +167 -0
- data/lib/ascribe/version.rb +3 -0
- data/lib/ascribe.rb +11 -0
- data/spec/ascribe_spec.rb +0 -0
- data/spec/spec_helper.rb +21 -0
- metadata +91 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
desc "Run specs"
|
6
|
+
RSpec::Core::RakeTask.new do |task|
|
7
|
+
task.pattern = "spec/**/*_spec.rb"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Run guard"
|
11
|
+
task :guard do
|
12
|
+
sh %{bundle exec guard start}
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Run spork"
|
16
|
+
task :spork do
|
17
|
+
sh %{bundle exec spork}
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# Bundler.require(:doc)
|
22
|
+
# desc "Generate documentation"
|
23
|
+
# YARD::Rake::YardocTask.new do |t|
|
24
|
+
# t.files = [ 'lib/**/*.rb' ]
|
25
|
+
# end
|
data/ascribe.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ascribe/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ascribe"
|
7
|
+
s.version = Ascribe::VERSION
|
8
|
+
s.authors = ["Dan Ryan"]
|
9
|
+
s.email = ["dan@appliedawesome.com"]
|
10
|
+
s.homepage = "https://github.com/danryan/ascribe"
|
11
|
+
s.summary = %q{Attributes for your Ruby objects}
|
12
|
+
s.description = %q{}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ascribe"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'activemodel', '3.0.10'
|
22
|
+
s.add_dependency 'yajl-ruby', '>= 0.8.2'
|
23
|
+
s.add_dependency 'rake', '>= 0.9.2'
|
24
|
+
# specify any dependencies here; for example:
|
25
|
+
# s.add_development_dependency "rspec"
|
26
|
+
# s.add_runtime_dependency "rest-client"
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Ascribe
|
2
|
+
class Attribute
|
3
|
+
attr_accessor :name, :type, :options, :default_value
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
options = args.extract_options!
|
7
|
+
@name, @type = args.shift.to_s, args.shift
|
8
|
+
self.options = (options || {}).symbolize_keys
|
9
|
+
self.default_value = self.options[:default]
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(value)
|
13
|
+
if value.nil? && !default_value.nil?
|
14
|
+
if default_value.respond_to?(:call)
|
15
|
+
return default_value.call
|
16
|
+
else
|
17
|
+
return Marshal.load(Marshal.dump(default_value))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
value
|
21
|
+
end
|
22
|
+
|
23
|
+
def set(value)
|
24
|
+
if type.kind_of?(Array)
|
25
|
+
if !value.nil? && !type.nil? && !type.include?(value.class)
|
26
|
+
raise Mastermind::ValidationError, "#{name} must be an instance of #{type}"
|
27
|
+
end
|
28
|
+
elsif type.kind_of?(Class)
|
29
|
+
if !value.nil? && !type.nil? && (!value.kind_of?(type) || type == nil)
|
30
|
+
raise Mastermind::ValidationError, "#{name} must be an instance of #{type}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require 'active_support/concern'
|
3
|
+
require 'active_support/hash_with_indifferent_access'
|
4
|
+
require 'ascribe/attribute'
|
5
|
+
|
6
|
+
module Ascribe
|
7
|
+
module Attributes
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
include ActiveModel::Validations
|
10
|
+
|
11
|
+
included do
|
12
|
+
extend ActiveSupport::DescendantsTracker
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
def inherited(base)
|
18
|
+
base.instance_variable_set(:@attributes, attributes.dup)
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def attributes
|
23
|
+
@attributes ||= {}
|
24
|
+
end
|
25
|
+
|
26
|
+
def attribute(*args)
|
27
|
+
Ascribe::Attribute.new(*args).tap do |attribute|
|
28
|
+
attributes[attribute.name.to_s] = attribute
|
29
|
+
create_attribute_in_descendants(*args)
|
30
|
+
create_validations_for(attribute)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def create_attribute_in_descendants(*args)
|
37
|
+
descendants.each {|descendant| descendant.attribute(*args) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_validations_for(attribute)
|
41
|
+
name = attribute.name
|
42
|
+
if attribute.options[:required]
|
43
|
+
validates_presence_of(name)
|
44
|
+
end
|
45
|
+
if attribute.options[:numeric]
|
46
|
+
number_options = attribute.type == Integer ? {:only_integer => true} : {}
|
47
|
+
validates_numericality_of(name, number_options)
|
48
|
+
end
|
49
|
+
if attribute.options[:format]
|
50
|
+
validates_format_of(name, :with => attribute.options[:format])
|
51
|
+
end
|
52
|
+
if attribute.options[:in]
|
53
|
+
validates_inclusion_of(name, :in => attribute.options[:in])
|
54
|
+
end
|
55
|
+
if attribute.options[:not_in]
|
56
|
+
validates_exclusion_of(name, :in => attribute.options[:not_in])
|
57
|
+
end
|
58
|
+
if attribute.options[:length]
|
59
|
+
length_options = case attribute.type
|
60
|
+
when Integer
|
61
|
+
{:minimum => 0, :maximum => key.options[:length]}
|
62
|
+
when Range
|
63
|
+
{:within => key.options[:length]}
|
64
|
+
when Hash
|
65
|
+
key.options[:length]
|
66
|
+
end
|
67
|
+
validates_length_of(name, length_options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
module InstanceMethods
|
74
|
+
def initialize(attrs={})
|
75
|
+
self.class.attributes.each_pair do |key, attribute|
|
76
|
+
(class << self; self; end).class_eval do
|
77
|
+
define_method(attribute.name) do |*value, &block|
|
78
|
+
if !block.nil?
|
79
|
+
write_attribute(attribute.name, block)
|
80
|
+
elsif !value.blank?
|
81
|
+
write_attribute(attribute.name, value.first)
|
82
|
+
else
|
83
|
+
read_attribute(attribute.name)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
define_method("#{attribute.name}=") do |*value, &block|
|
87
|
+
if !block.nil?
|
88
|
+
write_attribute(attribute.name, block)
|
89
|
+
elsif !value.blank?
|
90
|
+
write_attribute(attribute.name, value.first)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
assign_attributes(attrs)
|
96
|
+
end
|
97
|
+
|
98
|
+
def options
|
99
|
+
@options ||= {}
|
100
|
+
end
|
101
|
+
|
102
|
+
def assign_attributes(attrs)
|
103
|
+
attribute_keys.each do |attr_key|
|
104
|
+
value = read_attribute(attr_key)
|
105
|
+
write_attribute(attr_key, value)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Set all attributes supplied in the attrs hash
|
109
|
+
attrs.each_pair do |key, value|
|
110
|
+
if respond_to?(:"#{key}")
|
111
|
+
val =
|
112
|
+
write_attribute(key, value)
|
113
|
+
else
|
114
|
+
options[key] = value
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Iterate through
|
119
|
+
end
|
120
|
+
|
121
|
+
def update(attrs={})
|
122
|
+
assign_attributes(attrs)
|
123
|
+
end
|
124
|
+
|
125
|
+
def read_attribute(name)
|
126
|
+
if attribute = self.class.attributes[name.to_s]
|
127
|
+
value = attribute.get(instance_variable_get(:"@#{name}"))
|
128
|
+
instance_variable_set(:"@#{name}", value)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def write_attribute(name, value)
|
133
|
+
attribute = self.class.attributes[name.to_s]
|
134
|
+
instance_variable_set(:"@#{name}", attribute.set(value))
|
135
|
+
end
|
136
|
+
|
137
|
+
def attributes
|
138
|
+
attributes = {}
|
139
|
+
|
140
|
+
self.class.attributes.each do |key, attribute|
|
141
|
+
name = attribute.name
|
142
|
+
attributes[name] = read_attribute(name) if respond_to?(name)
|
143
|
+
end
|
144
|
+
return attributes
|
145
|
+
end
|
146
|
+
|
147
|
+
def attributes=(attrs={})
|
148
|
+
return if attrs.blank?
|
149
|
+
|
150
|
+
attrs.each_pair do |key, value|
|
151
|
+
if respond_to?(:"#{key}")
|
152
|
+
write_attribute(key, value)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def attribute_keys
|
158
|
+
self.class.attributes.keys
|
159
|
+
end
|
160
|
+
|
161
|
+
def to_hash
|
162
|
+
attributes.merge("options" => options)
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
data/lib/ascribe.rb
ADDED
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spork'
|
3
|
+
|
4
|
+
Spork.prefork do
|
5
|
+
require 'rspec'
|
6
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
7
|
+
require 'ascribe'
|
8
|
+
|
9
|
+
support_files = File.join(File.expand_path(File.dirname(__FILE__)), "spec/support/**/*.rb")
|
10
|
+
Dir[support_files].each {|f| require f}
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.color_enabled = true
|
14
|
+
config.mock_with :rspec
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Spork.each_run do
|
20
|
+
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ascribe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Ryan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-11 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activemodel
|
16
|
+
requirement: &70195220082180 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - =
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.10
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70195220082180
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yajl-ruby
|
27
|
+
requirement: &70195220081680 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.8.2
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70195220081680
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70195220081220 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.9.2
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70195220081220
|
47
|
+
description: ''
|
48
|
+
email:
|
49
|
+
- dan@appliedawesome.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- Gemfile
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- ascribe.gemspec
|
59
|
+
- lib/ascribe.rb
|
60
|
+
- lib/ascribe/attribute.rb
|
61
|
+
- lib/ascribe/attributes.rb
|
62
|
+
- lib/ascribe/version.rb
|
63
|
+
- spec/ascribe_spec.rb
|
64
|
+
- spec/spec_helper.rb
|
65
|
+
homepage: https://github.com/danryan/ascribe
|
66
|
+
licenses: []
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project: ascribe
|
85
|
+
rubygems_version: 1.8.8
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Attributes for your Ruby objects
|
89
|
+
test_files:
|
90
|
+
- spec/ascribe_spec.rb
|
91
|
+
- spec/spec_helper.rb
|