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

Parameters:

  • name (#to_sym)

    The name of the attribute and instance variable.

  • options (Hash, #to_hash) (defaults to: {})

    The options for defining and passing to the block.

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.

Returns:

  • (Object)


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