Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 core_ext
Octocat-spinner-32 lib
Octocat-spinner-32 spec
Octocat-spinner-32 tasks
Octocat-spinner-32 .gitignore
Octocat-spinner-32 Gemfile
Octocat-spinner-32 Gemfile.1.9.3
Octocat-spinner-32 MIT-LICENSE
Octocat-spinner-32 README
Octocat-spinner-32 Rakefile
Octocat-spinner-32 dsl_accessor.gemspec
README
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 <maiha@wota.jp>
Something went wrong with that request. Please try again.