dsl_accessor 0.1.0
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/History.txt +0 -0
- data/Manifest.txt +9 -0
- data/README.txt +97 -0
- data/Rakefile +49 -0
- data/lib/dsl_accessor/version.rb +9 -0
- data/lib/dsl_accessor.rb +52 -0
- data/setup.rb +1585 -0
- data/test/dsl_accessor_test.rb +120 -0
- data/test/test_helper.rb +3 -0
- metadata +72 -0
data/History.txt
ADDED
File without changes
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
= DslAccessor
|
2
|
+
|
3
|
+
This gem gives hybrid accessor class methods to classes by DSL like definition,
|
4
|
+
here hybrid means getter and setter. The accessor method acts as getter method
|
5
|
+
if no arguments given, otherwise it acts as setter one with the arguments.
|
6
|
+
|
7
|
+
|
8
|
+
=== Usage
|
9
|
+
|
10
|
+
class Foo
|
11
|
+
dsl_accessor "<METHOD NAME>"
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
=== Example
|
16
|
+
|
17
|
+
class Foo
|
18
|
+
dsl_accessor :greeting
|
19
|
+
end
|
20
|
+
|
21
|
+
This code gives 'greeting' class method to Foo class.
|
22
|
+
|
23
|
+
Foo.greeting # means getter, and the default value is nil.
|
24
|
+
=> nil
|
25
|
+
|
26
|
+
Foo.greeting "I'm Foo." # means setter with given arguments
|
27
|
+
=> "I'm Foo."
|
28
|
+
|
29
|
+
Foo.greeting
|
30
|
+
=> "I'm Foo."
|
31
|
+
|
32
|
+
|
33
|
+
=== Difference
|
34
|
+
|
35
|
+
I'm convinced that you want to propose me to use 'cattr_accessor'.
|
36
|
+
Although the difference is just whether we needs '=' operation or not,
|
37
|
+
it makes a large different on class definition especially subclass.
|
38
|
+
|
39
|
+
class Foo
|
40
|
+
cattr_accessor :greeting
|
41
|
+
end
|
42
|
+
|
43
|
+
class Bar < Foo
|
44
|
+
self.greeting = "I'm bar."
|
45
|
+
end
|
46
|
+
|
47
|
+
We must write redundant code represented by "self." to distinguish
|
48
|
+
a local variable and a class method when we use 'cattr_accessor'.
|
49
|
+
This is ugly and boring work.
|
50
|
+
|
51
|
+
class Foo
|
52
|
+
dsl_accessor :greeting
|
53
|
+
end
|
54
|
+
|
55
|
+
class Bar < Foo
|
56
|
+
greeting "I'm bar."
|
57
|
+
end
|
58
|
+
|
59
|
+
There are no longer redundant prefix code like "self." and "set_".
|
60
|
+
Don't you like this dsl-like coding with simple declaration?
|
61
|
+
|
62
|
+
|
63
|
+
=== Special Options
|
64
|
+
|
65
|
+
'dsl_accessor' method can take two options, those are :writer and :default.
|
66
|
+
"writer" option means callback method used when setter is executed.
|
67
|
+
"default" option means default static value or proc that creates some value.
|
68
|
+
|
69
|
+
class PseudoAR
|
70
|
+
dsl_accessor :primary_key, :default=>"id", :writer=>proc{|value| value.to_s}
|
71
|
+
dsl_accessor :table_name, :default=>proc{|klass| klass.name.demodulize.underscore.pluralize}
|
72
|
+
end
|
73
|
+
|
74
|
+
class Item < PseudoAR
|
75
|
+
end
|
76
|
+
|
77
|
+
class User < PseudoAR
|
78
|
+
primary_key :user_code
|
79
|
+
table_name :user_table
|
80
|
+
end
|
81
|
+
|
82
|
+
Item.primary_key # => "id"
|
83
|
+
Item.table_name # => "items"
|
84
|
+
User.primary_key # => "user_code"
|
85
|
+
User.table_name # => :user_table
|
86
|
+
|
87
|
+
Note that "User.primary_key" return a String by setter proc.
|
88
|
+
|
89
|
+
|
90
|
+
=== Install
|
91
|
+
|
92
|
+
gem install dsl_accessor
|
93
|
+
|
94
|
+
=== Author
|
95
|
+
|
96
|
+
Code: Maiha <anna@wota.jp>
|
97
|
+
Gem: Alex Wayne <rubyonrails@beautifulpixel.com>
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'hoe'
|
11
|
+
include FileUtils
|
12
|
+
require File.join(File.dirname(__FILE__), 'lib', 'dsl_accessor', 'version')
|
13
|
+
|
14
|
+
AUTHOR = ['Maiha', 'Alex Wayne'] # can also be an array of Authors
|
15
|
+
EMAIL = "anna@wota.jp"
|
16
|
+
DESCRIPTION = "This gem gives hybrid accessor class methods to classes by DSL like definition."
|
17
|
+
GEM_NAME = "dsl_accessor"
|
18
|
+
RUBYFORGE_PROJECT = "dsl-accessor"
|
19
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
20
|
+
RELEASE_TYPES = %w( gem )
|
21
|
+
|
22
|
+
|
23
|
+
NAME = "dsl_accessor"
|
24
|
+
REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
25
|
+
VERS = ENV['VERSION'] || (DslAccessor::VERSION::STRING + (REV ? ".#{REV}" : ""))
|
26
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
27
|
+
RDOC_OPTS = ['--quiet', '--title', "dsl_accessor documentation",
|
28
|
+
"--opname", "index.html",
|
29
|
+
"--line-numbers",
|
30
|
+
"--main", "README",
|
31
|
+
"--inline-source"]
|
32
|
+
|
33
|
+
# Generate all the Rake tasks
|
34
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
35
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
36
|
+
p.author = AUTHOR
|
37
|
+
p.description = DESCRIPTION
|
38
|
+
p.email = EMAIL
|
39
|
+
p.summary = DESCRIPTION
|
40
|
+
p.url = HOMEPATH
|
41
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
42
|
+
p.test_globs = ["test/**/*_test.rb"]
|
43
|
+
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
44
|
+
|
45
|
+
# == Optional
|
46
|
+
#p.changes - A description of the release's latest changes.
|
47
|
+
p.extra_deps = %w( activesupport )
|
48
|
+
#p.spec_extras - A hash of extra values to set in the gemspec.
|
49
|
+
end
|
data/lib/dsl_accessor.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class Class
|
4
|
+
def dsl_accessor(name, options = {})
|
5
|
+
raise TypeError, "DSL Error: options should be a hash. but got `#{options.class}'" unless options.is_a?(Hash)
|
6
|
+
writer = options[:writer] || options[:setter]
|
7
|
+
writer =
|
8
|
+
case writer
|
9
|
+
when NilClass then Proc.new{|value| value}
|
10
|
+
when Symbol then Proc.new{|value| __send__(writer, value)}
|
11
|
+
when Proc then writer
|
12
|
+
else raise TypeError, "DSL Error: writer should be a symbol or proc. but got `#{options[:writer].class}'"
|
13
|
+
end
|
14
|
+
write_inheritable_attribute(:"#{name}_writer", writer)
|
15
|
+
|
16
|
+
default =
|
17
|
+
case options[:default]
|
18
|
+
when NilClass then nil
|
19
|
+
when [] then Proc.new{[]}
|
20
|
+
when {} then Proc.new{{}}
|
21
|
+
when Symbol then Proc.new{__send__(options[:default])}
|
22
|
+
when Proc then options[:default]
|
23
|
+
else Proc.new{options[:default]}
|
24
|
+
end
|
25
|
+
write_inheritable_attribute(:"#{name}_default", default)
|
26
|
+
|
27
|
+
self.class.class_eval do
|
28
|
+
define_method("#{name}=") do |value|
|
29
|
+
writer = read_inheritable_attribute(:"#{name}_writer")
|
30
|
+
value = writer.call(value) if writer
|
31
|
+
write_inheritable_attribute(:"#{name}", value)
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method(name) do |*values|
|
35
|
+
if values.empty?
|
36
|
+
# getter method
|
37
|
+
key = :"#{name}"
|
38
|
+
if !inheritable_attributes.has_key?(key)
|
39
|
+
default = read_inheritable_attribute(:"#{name}_default")
|
40
|
+
value = default ? default.call(self) : nil
|
41
|
+
__send__("#{name}=", value)
|
42
|
+
end
|
43
|
+
read_inheritable_attribute(key)
|
44
|
+
else
|
45
|
+
# setter method
|
46
|
+
__send__("#{name}=", *values)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|