class NRSER::LazyAttr
Store the result of an attribute method (no args) in an instance variable of the same name and return that value on subsequent calls.
Public Class Methods
instance_var_name(target_method)
click to toggle source
Get the instance variable name for a target method.
@param [Method] target_method
The method the decorator is decorating.
@return [String]
The name of the instance variable, ready to be provided to `#instance_variable_set` (has `@` prefix).
# File lib/nrser/meta/lazy_attr.rb, line 36 def self.instance_var_name target_method name = target_method.name.to_s # Allow predicate methods by chopping off the `?` character. # # Other stupid uses like `+` or whatever will raise when # `#instance_variable_set` is called. # name = name[0..-2] if name.end_with? '?' "@#{ name }" end
Public Instance Methods
call(target_method, receiver, *args, &block)
click to toggle source
Execute the decorator.
@param [Method] target_method
The decorated method, already bound to the receiver. The `method_decorators` gem calls this `orig`, but I thought `target_method` made more sense.
@param [*] receiver
The object that will receive the call to `target`. The `method_decorators` gem calls this `this`, but I thought `receiver` made more sense. It's just `target.receiver`, but the API is how it is.
@param [Array] args
Any arguments the decorated method was called with.
@param [Proc?] block
The block the decorated method was called with (if any).
@return
Whatever `target_method` returns.
# File lib/nrser/meta/lazy_attr.rb, line 75 def call target_method, receiver, *args, &block unless target_method.parameters.empty? raise NRSER::ArgumentError.new \ "{NRSER::LazyAttr} can only decorate methods with 0 params", receiver: receiver, target_method: target_method end unless args.empty? raise NRSER::ArgumentError.new \ "wrong number of arguments for", target_method, "(given", args.length, "expected 0)", receiver: receiver, target_method: target_method end unless block.nil? raise NRSER::ArgumentError.new \ "wrong number of arguments (given #{ args.length }, expected 0)", receiver: receiver, target_method: target_method end var_name = self.class.instance_var_name target_method unless receiver.instance_variable_defined? var_name receiver.instance_variable_set var_name, target_method.call end receiver.instance_variable_get var_name end