mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Implement mattr_acessor :default option
This commit is contained in:
parent
ab4f811d09
commit
a5b0c60714
3 changed files with 65 additions and 25 deletions
|
@ -1,3 +1,12 @@
|
|||
* Add default option to module and class attribute accessors.
|
||||
|
||||
mattr_accessor :settings, default: {}
|
||||
|
||||
Works for `mattr_reader`, `mattr_writer`, `cattr_accessor`, `cattr_reader`,
|
||||
and `cattr_writer` as well.
|
||||
|
||||
*Genadi Samokovarov*
|
||||
|
||||
* Add `Date#prev_occurring` and `Date#next_occurring` to return specified next/previous occurring day of week.
|
||||
|
||||
*Shota Iguchi*
|
||||
|
|
|
@ -38,13 +38,10 @@ class Module
|
|||
#
|
||||
# Person.new.hair_colors # => NoMethodError
|
||||
#
|
||||
#
|
||||
# Also, you can pass a block to set up the attribute with a default value.
|
||||
# You can set a default value for the attribute.
|
||||
#
|
||||
# module HairColors
|
||||
# mattr_reader :hair_colors do
|
||||
# [:brown, :black, :blonde, :red]
|
||||
# end
|
||||
# mattr_reader :hair_colors, default: [:brown, :black, :blonde, :red]
|
||||
# end
|
||||
#
|
||||
# class Person
|
||||
|
@ -52,8 +49,7 @@ class Module
|
|||
# end
|
||||
#
|
||||
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
||||
def mattr_reader(*syms)
|
||||
options = syms.extract_options!
|
||||
def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil)
|
||||
syms.each do |sym|
|
||||
raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
|
||||
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
||||
|
@ -64,14 +60,16 @@ class Module
|
|||
end
|
||||
EOS
|
||||
|
||||
unless options[:instance_reader] == false || options[:instance_accessor] == false
|
||||
if instance_reader && instance_accessor
|
||||
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
||||
def #{sym}
|
||||
@@#{sym}
|
||||
end
|
||||
EOS
|
||||
end
|
||||
class_variable_set("@@#{sym}", yield) if block_given?
|
||||
|
||||
sym_default_value = (block_given? && default.nil?) ? yield : default
|
||||
class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil?
|
||||
end
|
||||
end
|
||||
alias :cattr_reader :mattr_reader
|
||||
|
@ -107,12 +105,10 @@ class Module
|
|||
#
|
||||
# Person.new.hair_colors = [:blonde, :red] # => NoMethodError
|
||||
#
|
||||
# Also, you can pass a block to set up the attribute with a default value.
|
||||
# You can set a default value for the attribute.
|
||||
#
|
||||
# module HairColors
|
||||
# mattr_writer :hair_colors do
|
||||
# [:brown, :black, :blonde, :red]
|
||||
# end
|
||||
# mattr_writer :hair_colors, default: [:brown, :black, :blonde, :red]
|
||||
# end
|
||||
#
|
||||
# class Person
|
||||
|
@ -120,8 +116,7 @@ class Module
|
|||
# end
|
||||
#
|
||||
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
||||
def mattr_writer(*syms)
|
||||
options = syms.extract_options!
|
||||
def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil)
|
||||
syms.each do |sym|
|
||||
raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
|
||||
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
||||
|
@ -132,14 +127,16 @@ class Module
|
|||
end
|
||||
EOS
|
||||
|
||||
unless options[:instance_writer] == false || options[:instance_accessor] == false
|
||||
if instance_writer && instance_accessor
|
||||
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
||||
def #{sym}=(obj)
|
||||
@@#{sym} = obj
|
||||
end
|
||||
EOS
|
||||
end
|
||||
send("#{sym}=", yield) if block_given?
|
||||
|
||||
sym_default_value = (block_given? && default.nil?) ? yield : default
|
||||
send("#{sym}=", sym_default_value) unless sym_default_value.nil?
|
||||
end
|
||||
end
|
||||
alias :cattr_writer :mattr_writer
|
||||
|
@ -197,12 +194,10 @@ class Module
|
|||
# Person.new.hair_colors = [:brown] # => NoMethodError
|
||||
# Person.new.hair_colors # => NoMethodError
|
||||
#
|
||||
# Also you can pass a block to set up the attribute with a default value.
|
||||
# You can set a default value for the attribute.
|
||||
#
|
||||
# module HairColors
|
||||
# mattr_accessor :hair_colors do
|
||||
# [:brown, :black, :blonde, :red]
|
||||
# end
|
||||
# mattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red]
|
||||
# end
|
||||
#
|
||||
# class Person
|
||||
|
@ -210,9 +205,9 @@ class Module
|
|||
# end
|
||||
#
|
||||
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
||||
def mattr_accessor(*syms, &blk)
|
||||
mattr_reader(*syms, &blk)
|
||||
mattr_writer(*syms)
|
||||
def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk)
|
||||
mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, &blk)
|
||||
mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default)
|
||||
end
|
||||
alias :cattr_accessor :mattr_accessor
|
||||
end
|
||||
|
|
|
@ -12,7 +12,14 @@ class ModuleAttributeAccessorTest < ActiveSupport::TestCase
|
|||
cattr_accessor(:defa) { "default_accessor_value" }
|
||||
cattr_reader(:defr) { "default_reader_value" }
|
||||
cattr_writer(:defw) { "default_writer_value" }
|
||||
cattr_accessor(:deff) { false }
|
||||
cattr_accessor(:quux) { :quux }
|
||||
|
||||
cattr_accessor :def_accessor, default: "default_accessor_value"
|
||||
cattr_reader :def_reader, default: "default_reader_value"
|
||||
cattr_writer :def_writer, default: "default_writer_value"
|
||||
cattr_accessor :def_false, default: false
|
||||
cattr_accessor(:def_priority, default: false) { :no_priority }
|
||||
end
|
||||
@class = Class.new
|
||||
@class.instance_eval { include m }
|
||||
|
@ -24,6 +31,21 @@ class ModuleAttributeAccessorTest < ActiveSupport::TestCase
|
|||
assert_nil @object.foo
|
||||
end
|
||||
|
||||
def test_mattr_default_keyword_arguments
|
||||
assert_equal "default_accessor_value", @module.def_accessor
|
||||
assert_equal "default_reader_value", @module.def_reader
|
||||
assert_equal "default_writer_value", @module.class_variable_get(:@@def_writer)
|
||||
end
|
||||
|
||||
def test_mattr_can_default_to_false
|
||||
assert_equal false, @module.def_false
|
||||
assert_equal false, @module.deff
|
||||
end
|
||||
|
||||
def test_mattr_default_priority
|
||||
assert_equal false, @module.def_priority
|
||||
end
|
||||
|
||||
def test_should_set_mattr_value
|
||||
@module.foo = :test
|
||||
assert_equal :test, @object.foo
|
||||
|
@ -91,9 +113,23 @@ class ModuleAttributeAccessorTest < ActiveSupport::TestCase
|
|||
assert_equal "default_writer_value", @module.class_variable_get("@@defw")
|
||||
end
|
||||
|
||||
def test_should_not_invoke_default_value_block_multiple_times
|
||||
def test_method_invocation_should_not_invoke_the_default_block
|
||||
count = 0
|
||||
|
||||
@module.cattr_accessor(:defcount) { count += 1 }
|
||||
|
||||
assert_equal 1, count
|
||||
assert_no_difference "count" do
|
||||
@module.defcount
|
||||
end
|
||||
end
|
||||
|
||||
def test_declaring_multiple_attributes_at_once_invokes_the_block_multiple_times
|
||||
count = 0
|
||||
|
||||
@module.cattr_accessor(:defn1, :defn2) { count += 1 }
|
||||
|
||||
assert_equal 1, @module.defn1
|
||||
assert_equal 2, @module.defn2
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue