Module: HasHelpers::Attributes::GuardedAttributes::ClassMethods

Defined in:
lib/has_helpers/attributes.rb

Instance Method Summary collapse

Instance Method Details

#guarded_attr_accessor(*args, guard: nil, memoize: true, guard_nil: nil, auto_guard: false, collection: false, &block) ⇒ Object

Use this like you would use attr_accessor. The writer method is the same as the standard Ruby attr_writer, but the reader method will be generated using guarded_attr_reader (see that method for details.)



55
56
57
58
# File 'lib/has_helpers/attributes.rb', line 55

def guarded_attr_accessor(*args, guard: nil, memoize: true, guard_nil: nil, auto_guard: false, collection: false, &block)
  attr_writer(*args)
  guarded_attr_reader(*args, guard: guard, memoize: memoize, guard_nil: guard_nil, auto_guard: auto_guard, collection: collection, &block)
end

#guarded_attr_reader(*args, guard: nil, memoize: true, guard_nil: nil, auto_guard: false, collection: false, &block) ⇒ Object

guarded_attr_reader is intended to be used in place of Ruby's standard attr_reader. However, this provides memoization by default and the option to provide a guard Proc which will always be run against the value.

The return value (prior to running the guard proc) is the result of the given block or the instance variable which matches the accessor name (e.g. The ivar @x for guard_attr_reader :x).

Options

guard: This may be set to either a Proc object or an object which is convertible to a Proc through #to_proc. The determined value (returned from the block, or fetched from the matching instance variable) will be passed into the Proc. This happens prior to memoization, if enabled.

memoize: This is enabled by default, but it may be disabled by setting this option to false. Note that memoization happens after execution of both the block and the guard proc, if either or both of those are given.

guard_nil: When set to true, the guard Proc will be executed even when the argument value is nil. This is false by default.

auto_guard: This will automatically generate a guard Proc using a symbol :to_attr, based on the name of the attribute. It is a shorthand for setting the guard explicitly for each attribute.

This example:

guarded_attr_accessor :service, :icon, :action, auto_guard: true

is equivalent to this:

guarded_attr_accessor :service, guard: :to_service
guarded_attr_accessor :icon, guard: :to_icon
guarded_attr_accessor :action, guard: :to_action

Examples

class Foo include ::HasHelpers::Attributes guarded_attr_accessor :bar guarded_attr_accessor :bar_with_block do "Already set to: #{ @bar_with_block }" end guarded_attr_accessor :bar_with_guard, guard: -> value { value.upcase } guarded_attr_accessor :bar_with_symbol_as_guard, guard: :to_i guarded_attr_accessor :bar_with_block_and_guard, guard: -> value { value.downcase } do "I cOmE fRoM cLaSs #{ self.class.name }" end end

foo = Foo.new
foo.bar                                  # => nil
foo.bar = 42
foo.bar                                  # => 42
foo.bar_with_block = "Derp"
foo.bar_with_block                       # => "Already set to: Derp"
foo.bar_with_guard = "hello"
foo.bar_with_guard                       # => "HELLO"
foo.bar_with_symbol_as_guard = "123.45"
foo.bar_with_symbol_as_guard             # => 123
foo.bar_with_block_and_guard             # => "i come from class c"

Using guard class Foo include ::HasHelpers::Attributes guarded_attr_accessor :action, guard: :to_action end

foo = Foo.new
foo.action                         # => nil
foo.action = { :name => "Find" }
foo.action                         # => #<Action @name="Find">


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/has_helpers/attributes.rb', line 133

def guarded_attr_reader(*args, guard: nil, memoize: true, guard_nil: nil, auto_guard: false, collection: false, &block)
  args.each do |attr|
    ivar_memo = "@#{ attr }_memoized"
    ivar_memo_indicator = "@#{ attr }_memoized_indicator" # Use to indicate whether memoization has already happened.
    guard_object = guard || (auto_guard && "to_#{ attr.to_s.singularize }".to_sym)
    define_method(attr) do |*attr_args|
      if memoize
        if instance_variable_get(ivar_memo_indicator)
          instance_variable_get(ivar_memo)
        else
          instance_variable_set(ivar_memo_indicator, true)
          instance_variable_set(ivar_memo, exec_guard(guard_object, value_for(attr, attr_args, collection, block), guard_nil: guard_nil, collection: collection))
        end
      else
        exec_guard(guard_object, value_for(attr, attr_args, collection, block), guard_nil: guard_nil, collection: collection)
      end
    end
  end
end

#guarded_collection(*args, guard: nil, memoize: true, guard_nil: nil, auto_guard: false, &block) ⇒ Object



153
154
155
# File 'lib/has_helpers/attributes.rb', line 153

def guarded_collection(*args, guard: nil, memoize: true, guard_nil: nil, auto_guard: false, &block)
  guarded_attr_accessor(*args, guard: guard, memoize: memoize, guard_nil: guard_nil, auto_guard: auto_guard, collection: true, &block)
end