Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow block to be specified for cattr_reader, also add default param #49

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions motion/core_ext/class/attribute_accessors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def cattr_reader(*syms)
raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
class_exec do
unless class_variable_defined?("@@#{sym}")
class_variable_set("@@#{sym}", nil)
class_variable_set("@@#{sym}", block_given? ? yield : options[:default])
end

define_singleton_method sym do
Expand Down Expand Up @@ -94,7 +94,7 @@ def cattr_writer(*syms)
raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
class_exec do
unless class_variable_defined?("@@#{sym}")
class_variable_set("@@#{sym}", nil)
class_variable_set("@@#{sym}", block_given? ? yield : options[:default])
end

define_singleton_method "#{sym}=" do |obj|
Expand All @@ -109,7 +109,6 @@ def cattr_writer(*syms)
end
end
end
send("#{sym}=", yield) if block_given?
end
end

Expand Down Expand Up @@ -161,8 +160,17 @@ def cattr_writer(*syms)
# end
#
# Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red]
#
# Or by specifying a default
#
# class Person
# cattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red]
# end
#
# Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red]

def cattr_accessor(*syms, &blk)
cattr_reader(*syms)
cattr_reader(*syms, &blk)
cattr_writer(*syms, &blk)
end
end
8 changes: 6 additions & 2 deletions motion/duration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module MotionSupport
# Time#advance, respectively. It mainly supports the methods on Numeric.
#
# 1.month.ago # equivalent to Time.now.advance(months: -1)
class Duration < BasicObject
class Duration
attr_accessor :value, :parts

def initialize(value, parts) #:nodoc:
Expand Down Expand Up @@ -79,7 +79,11 @@ def as_json(options = nil) #:nodoc:
to_i
end

protected
def to_json
as_json.to_json
end

protected

def sum(sign, time = ::Time.now) #:nodoc:
parts.inject(time) do |t,(type,number)|
Expand Down
56 changes: 39 additions & 17 deletions spec/motion-support/core_ext/class/attribute_accessor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,60 @@ class CAttrAccessorDerived < CAttrAccessorBase
cattr_accessor :bar, :instance_writer => false
cattr_reader :shaq, :instance_reader => false
cattr_accessor :camp, :instance_accessor => false
cattr_reader :rdrb do 'block' end
cattr_reader :rdrd, :default => 'default'
end
@object = @class.new
end

describe "reader" do
it "should return nil by default" do
@class.foo.should.be.nil
end

it "should return nil by default for instance" do
@object.foo.should.be.nil
end

it "should return block if one was present" do
@class.rdrb.should == 'block'
end

it "should return block if one was present for instance" do
@object.rdrb.should == 'block'
end

it "should return default if one was specified" do
@class.rdrd.should == 'default'
end

it "should return default if one was given for instance" do
@object.rdrd.should == 'default'
end
end

describe "writer" do
it "should set value" do
@class.foo = :test
@class.foo.should == :test
end

it "should set value through instance writer" do
@object.foo = :bar
@object.foo.should == :bar
end

it "should set instance reader's value through module's writer" do
@class.foo = :test
@object.foo.should == :test
end

it "should set module reader's value through instances's writer" do
@object.foo = :bar
@class.foo.should == :bar
end
end

describe "instance_writer => false" do
it "should not create instance writer" do
@class.should.respond_to :foo
Expand All @@ -55,14 +77,14 @@ class CAttrAccessorDerived < CAttrAccessorBase
@object.should.not.respond_to :bar=
end
end

describe "instance_reader => false" do
it "should not create instance reader" do
@class.should.respond_to :shaq
@object.should.not.respond_to :shaq
end
end

describe "instance_accessor => false" do
it "should not create reader or writer" do
@class.should.respond_to :camp
Expand All @@ -71,7 +93,7 @@ class CAttrAccessorDerived < CAttrAccessorBase
end
end
end

describe "invalid attribute accessors" do
it "should raise NameError when creating an invalid reader" do
lambda do
Expand All @@ -80,7 +102,7 @@ class CAttrAccessorDerived < CAttrAccessorBase
end
end.should.raise NameError
end

it "should raise NameError when creating an invalid writer" do
lambda do
Class.new do
Expand All @@ -89,36 +111,36 @@ class CAttrAccessorDerived < CAttrAccessorBase
end.should.raise NameError
end
end

describe "inheritance" do
it "should be accessible in the base class and the derived class" do
CAttrAccessorBase.respond_to?(:empty_accessor).should == true
CAttrAccessorDerived.respond_to?(:empty_accessor).should == true
end

it "should return nil for an unset accessor in the base class" do
CAttrAccessorBase.empty_accessor.should == nil
end

it "should return nil for an unset accessor in the derived class" do
CAttrAccessorDerived.empty_accessor.should == nil
end

it "should return a value for an accessor set in the base class in the base class" do
CAttrAccessorBase.base_accessor = 10
CAttrAccessorBase.base_accessor.should == 10
end

it "should return a value for an accessor set in the base class in the derived class" do
CAttrAccessorBase.base_accessor = 10
CAttrAccessorDerived.base_accessor.should == 10
end

it "should return a value for the base class if set for the derived class" do
CAttrAccessorDerived.derived_accessor = 20
CAttrAccessorBase.derived_accessor.should == 20
end

it "should return a value for an accessor set in the derived class in the derived class" do
CAttrAccessorDerived.derived_accessor = 20
CAttrAccessorDerived.derived_accessor.should == 20
Expand Down