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 ADDED
File without changes
data/Manifest.txt ADDED
@@ -0,0 +1,9 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ setup.rb
6
+ lib/dsl_accessor.rb
7
+ lib/dsl_accessor/version.rb
8
+ test/test_helper.rb
9
+ test/dsl_accessor_test.rb
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
@@ -0,0 +1,9 @@
1
+ module DslAccessor #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -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
+