DslAccessor
This plugin gives hybrid accessor class methods to classes by DSL like definition,
here hybrid means getter and setter. The accessor method acts as getter method
if no argments given, otherwise it acts as setter one with the arguments.
Install
gem install dsl_accessor
Usage
class Foo
dsl_accessor "<METHOD NAME>" (, default_value)
end
Example
class Foo
dsl_accessor :greeting
end
This code gives 'greeting' class method to Foo class.
Foo.greeting # means getter, and the default value is nil.
=> nil
Foo.greeting "I'm Foo." # means setter with given arguments
=> "I'm Foo."
Foo.greeting
=> "I'm Foo."
Difference
I am convinced that you want to propose me to use 'cattr_accessor'.
Although the difference is just whether we needs '=' operation or not,
it makes a large different on class definition especially subclass.
class Foo
cattr_accessor :greeting
end
class Bar < Foo
self.greeting = "I am bar."
end
We must write redundant code represented by "self." to distinguish
a local variable and a class method when we use 'cattr_accessor'.
This is ugly and boring work.
class Foo
dsl_accessor :greeting
end
class Bar < Foo
greeting "I am bar."
end
There are no longer redundant prefix code like "self." and "set_".
How about this dsl-like coding with simple declaration?
Special Options
'dsl_accessor' method can take two options, those are :writer and :default.
"writer" option means callback method used when setter is executed.
"default" option means default static value or proc that creates some value.
class PseudoAR
dsl_accessor :primary_key, :default=>"id", :writer=>proc{|value| value.to_s}
dsl_accessor :table_name, :default=>proc{|klass| klass.name.demodulize.underscore.pluralize}
end
class Item < PseudoAR
end
class User < PseudoAR
primary_key :user_code
table_name :user_table
end
Item.primary_key # => "id"
Item.table_name # => "items"
User.primary_key # => "user_code"
User.table_name # => :user_table
Note that "User.primary_key" return a String by setter proc.
Instance Method
"instance" option automatically defines its instance method
class Search
dsl_accessor :url, :instance=>true, :default=>"http://localhost/"
end
Search.url # => "http://localhost/"
Search.new.url # => "http://localhost/"
and it uses @options instance variable with special value :options
class Window
dsl_accessor :width, :default=>640, :instance=>:options
def initialize(options = {})
@options = options
end
end
Window.width # => 640
Window.new.width # => 640
window = Window.new(:width=>320)
window.width # =>320
Auto declared mode
It was removed at version 0.4.
In 0.4.1 or higher, use dsl_accessor block instead.
with block
dsl_accessor method accepts block for auto declared mode.
In this mode, we can define methods like dsl.
[NOTE]
1. This affects only methods with a block and no other args.
class Foo
dsl_accessor do
foo {1} # Foo.foo is defined
bar(a) # NoMethodError
baz(a) {2} # NoMethodError
end
end
2. When :instance is passed with block, it affects instance methods.
class Foo
dsl_accessor :instance do
foo {1} # Foo#foo is defined
bar(a) # NoMethodError (same as class)
end
end
3. This will damage on your class cause it easily updates existing methods.
Foo.name # => 'Foo'
class Foo
dsl_accessor do
name {1}
end
end
Foo.name # => 1
Although there is a risk on above, it helps you when many one-lined methods exist.
class Foo
def last
num_pages
end
def first?
page == 1
end
def offset
model.proxy_options[:offset]
end
end
Refactored with dsl_accessor
class Foo
dsl_accessor :instance do
last {num_pages}
first? {page == 1}
offset {model.proxy_options[:offset]}
end
end
Homepage
http://github.com/maiha/dsl_accessor
Author
Maiha <[email protected]>