Module: Aspect::HasAttributes::ClassMethods

Defined in:
lib/aspect/has_attributes.rb

Overview

The class methods to extend into the object HasAttributes was included in.

Instance Method Summary collapse

Instance Method Details

#attribute(name, options = {}) {|value, options| ... } ⇒ Object

Define an attribute on the object.

Examples:

Simple accessor

class User
  include Aspect::HasAttributes

  attribute(:name)
end

user = User.new
user.name = "Ezio Auditore"
user.name # => "Ezio Auditore"

Simple getter

class User
  include Aspect::HasAttributes

  attribute(:name, setter: false)

  def initialize(name)
    @name = name
  end
end

user = User.new("Ezio Auditore")
user.name # => "Ezio Auditore"

Simple setter

class User
  include Aspect::HasAttributes

  attribute(:name, getter: false)

  def name
    @name.strip
  end
end

user = User.new
user.name = "  Ezio Auditore  "
user.name # => "Ezio Auditore"

Accessor with block

class User
  include Aspect::HasAttributes

  attribute(:name) { |value| value.to_s.strip }
end

user = User.new
user.name = "  Ezio Auditore  "
user.name # => "Ezio Auditore"

Accessor with block, passing options

class User
  include Aspect::HasAttributes

  conversion_block = Proc.new { |value, options| "#{options[:prefix]}-#{value.to_s.strip}" }
  attribute(:foo, prefix: "Foo", &conversion_block)
  attribute(:bar, prefix: "Bar", &conversion_block)
end

user = User.new
user.foo = "  Thing  "
user.foo # => "Foo-Thing"
user.bar = "   Thingy"
user.bar # => "Bar-Thingy"

Query accessor

class User
  include Aspect::HasAttributes

  attribute(:admin, query: true)
end

user = User.new
user.admin? # => false
user.admin = "yep" # Accepts truthy values
user.admin? # => true

Query accessor with block

class User
  include Aspect::HasAttributes

  attribute(:moderator, query: true)
  attribute(:admin, query: true) { |value| @moderator && value }
end

user = User.new

user.moderator? # => false
user.admin? # => false
user.admin = true
user.admin? # => false

user.moderator = true
user.moderator? # => true
user.admin? # => false
user.admin = true
user.moderator? # => true
user.admin? # => true

Options Hash (options):

  • :getter (Boolean) — default: true

    Determines whether to define an attribute getter.

  • :setter (Boolean) — default: true

    Determines whether to define an attribute setter.

  • :query (Boolean) — default: false

    Determines whether to define as a query attribute, with the getter having a question mark appended to the method name and the setter converting the value or block into a boolean using bang-bang (‘!!`).

Yield Parameters:

  • value (Object)

    The value given to the setter method.

  • options (Hash)

    The options given when defining, given to the setter method.

Yield Returns:

  • (Object)

    The value to set the instance variable as.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/aspect/has_attributes.rb', line 151

def attribute(name, options={}, &block) # TODO: Should break out into protected methods?
  name = name.to_sym

  options = options.to_h unless options.is_a?(Hash)
  options = { getter: true, setter: true }.merge(options)

  if options[:getter]
    options[:getter] = options[:getter] == true ? {} : options[:getter].to_h

    method_name = options[:query] ? "#{name}?" : name
    define_method(method_name) do
      value = instance_variable_get("@#{name}")

      options[:query] ? !!value : value
    end
  end

  if options[:setter]
    options[:setter] = options[:setter] == true ? {} : options[:setter].to_h

    define_method("#{name}=") do |value|
      value = instance_exec(value, options, &block) unless block.nil?
      value = options[:query] ? !!value : value

      instance_variable_set("@#{name}", value)
    end
  end

  self
end