dsl_accessor 0.1.0

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