Skip to content

Instantly share code, notes, and snippets.

@vderyagin
Created May 18, 2011 05:12
Show Gist options
  • Save vderyagin/978029 to your computer and use it in GitHub Desktop.
Save vderyagin/978029 to your computer and use it in GitHub Desktop.
Gain class-level accessor methods by including module in your class
#! /usr/bin/env ruby
module ClassAccessors
def self.included(klass)
class << klass
def class_attr_reader(*args)
args.each do |attr|
define_singleton_method attr do
instance_variable_get "@#{attr}"
end
end
end
def class_attr_writer(*args)
args.each do |attr|
define_singleton_method "#{attr}=" do |val|
instance_variable_set "@#{attr}", val
end
end
end
def class_attr_accessor(*args)
class_attr_reader(*args)
class_attr_writer(*args)
end
end
end
end
#! /usr/bin/env ruby
require_relative 'class_accessors'
# ensure using gem version, not the one built into YARV
# require 'rubygems'; gem 'minitest'
require 'minitest/autorun'
describe ClassAccessors do
before do
@klass = Class.new do
include ClassAccessors
class_attr_reader :a, :bar
class_attr_writer :b, :baz
class_attr_accessor :c
end
end
after do
@klass = nil
end
it 'should have readers' do
@klass.must_respond_to :a
@klass.must_respond_to :c
@klass.must_respond_to :bar
end
it 'should have writers' do
@klass.must_respond_to :'b='
@klass.must_respond_to :'c='
@klass.must_respond_to :'baz='
end
it 'should not have too much readers and writers' do
@klass.wont_respond_to :'a='
@klass.wont_respond_to :'bar='
@klass.wont_respond_to :b
@klass.wont_respond_to :baz
end
it 'should get values' do
@klass.a.must_be_nil
lambda { @klass.instance_eval { @a = 85 } }.call
@klass.a.must_equal 85
lambda { @klass.instance_eval { @a = 82 } }.call
@klass.a.must_equal 82
@klall.bar.must_be_nil
lambda { @klass.instance_eval { @bar = 5 } }.call
@klass.bar.must_equal 5
lambda { @klass.instance_eval { @bar = 6 } }.call
@klass.bar.must_equal 6
end
it 'should set values' do
lambda { @klass.instance_eval { @b } }.call.must_be_nil
@klass.b = 21
lambda { @klass.instance_eval { @b } }.call.must_equal 21
@klass.b = 5
lambda { @klass.instance_eval { @b } }.call.must_equal 5
lambda { @klass.instance_eval { @baz } }.call.must_be_nil
@klass.baz = "aa"
lambda { @klass.instance_eval { @baz } }.call.must_equal "aa"
@klass.baz = "foo"
lambda { @klass.instance_eval { @baz } }.call.must_equal "foo"
end
it 'should get and set values' do
@klass.c.must_be_nil
@klass.c = 4
@klass.c.must_equal 4
@klass.c = 33
@klass.c.must_equal 33
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment