Module: PowerConverter

Defined in:
lib/power_converter.rb,
lib/power_converter/version.rb

Overview

:nodoc:

Defined Under Namespace

Classes: ConversionError, ConverterNotFoundError

Constant Summary collapse

CONVERSION_METHOD_PREFIX =

When building a dynamic conversion method this is its prefix.

"convert_to_".freeze
CONVERSION_METHOD_REGEXP =

Useful for when you want to know if a method name is a valid conversion method name.

/\A#{CONVERSION_METHOD_PREFIX}(.+)\Z/
VERSION =

:nodoc:

"0.1.2".freeze

Class Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, **kwargs, &block) ⇒ Object (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Handle attempts to call module level conversions directly off of the PowerConverter module.

Examples:

PowerConverter.define_conversion_for(:boolean) { |input| ... }
PowerConverter.convert_to_boolean(a_value)

Parameters:

  • method_name (Symbol)
  • args (Array)

    splat arguements that would be passed on-ward

  • kwargs (Hash)

    keyword arguements

  • block (#call)

See Also:

Since:

  • 0.0.2



256
257
258
259
260
261
262
263
# File 'lib/power_converter.rb', line 256

def method_missing(method_name, *args, **kwargs, &block)
  named_converter = extract_named_converter_from(method_name)
  if named_converter
    convert(*args, kwargs.merge(to: named_converter), &block)
  else
    super
  end
end

Class Method Details

.convert(value, options = {}) { ... } ⇒ Object

Convert the given ‘value` via the named `:to` converter. As a short-circuit if the given `value` publicly responds to a `to_<named_converter>` it will use that.

Examples:

PowerConverter.convert('true', to: :boolean)
class Foo
  def to_bar
    :hello_world
  end
end

PowerConverter.convert(Foo.new, to: :bar)
=> :hello_world

Parameters:

  • value (Object)

    the thing that you will be converting

  • options (Hash) (defaults to: {})

    the options used to perform the conversion

Options Hash (options):

  • :to (Symbol)

    the named_conversion that has been registered

Yields:

  • Yield control to caller if the value could not be converted; This is a good fallback mechanism.

Returns:

  • (Object)

    the resulting converted object

Raises:

See Also:

Since:

  • 0.0.1



155
156
157
158
159
160
161
162
163
# File 'lib/power_converter.rb', line 155

def convert(value, options = {})
  named_converter = options.fetch(:to)
  scope = options.fetch(:scope, nil)
  return value.public_send("to_#{named_converter}") if value.respond_to?("to_#{named_converter}", false)
  returning_value = converter_for(named_converter).call(value, *scope)
  return returning_value unless returning_value.nil?
  return yield if block_given?
  raise ConversionError.new(value, options)
end

.converter_for(named_conversion) ⇒ #call

Note:

There are no protections for infinite alias loops.

Given the ‘named_conversion` find and retrieve the defined converter.

Examples:

PowerConverter.converter_for(:boolean).call(value)

Parameters:

  • named_conversion (String, Symbol)

Returns:

  • (#call)

    a registered converter

Raises:

See Also:

Since:

  • 0.0.1



218
219
220
221
222
223
# File 'lib/power_converter.rb', line 218

def converter_for(named_conversion)
  key = named_conversion.to_s
  return defined_conversions[key] if defined_conversions.key?(key)
  return converter_for(aliased_conversions[key]) if aliased_conversions.key?(key)
  raise ConverterNotFoundError.new(named_conversion, defined_converter_names)
end

.define_alias(aliased_named_conversion, options = {}) ⇒ Object

You may define an alias of a defined (or to be defined) power converter.

Examples:

PowerConverter.define_alias(:true_or_false, is_alias_of: :boolean)

Parameters:

  • aliased_named_conversion (String, Symbol)

    the name of the conversion that you are declaring.

  • options (Hash) (defaults to: {})

    the options used to perform the conversion

Options Hash (options):

  • :is_alias_of (Symbol)

    the aliased_named_conversion that we will be using for to perform the conversion.

Returns:

  • void

Since:

  • 0.0.4



117
118
119
120
# File 'lib/power_converter.rb', line 117

def define_alias(aliased_named_conversion, options = {})
  @aliased_conversions ||= {}
  @aliased_conversions[aliased_named_conversion.to_s] = options.fetch(:is_alias_of)
end

.define_conversion_for(named_conversion, &converter) {|value| ... } ⇒ Object

TODO:

Make sure that the converter requires at least one parameter.

Note:

If your defined converter returns ‘nil`, it is assumed that the conversion failed and a [PowerConverter::ConversionError] exception will be thrown.

Note:

The conversion module/method that is created may not adhear to the exact idiom (a method defined in CamelCase)

Responsible for defining a conversion method and a “shovel-ready” conversion module; because maybe you want a mixin for convenience reasons.

Examples:

PowerConverter.define_conversion_for :boolean do |input|
  case input
  when false, 0, '0', 'false', 'no', nil then false
  else
    true
  end
end

PowerConverter.convert(object, to: :boolean)
PowerConverter.convert_to_boolean(object)

Parameters:

  • named_conversion (String, Symbol)

    the name of the conversion that you are declaring.

  • converter (#call)

    the callable object that will perform the conversion.

Yields:

  • (value)

    A block that will be used to convert the given value to the named thing.

Yield Returns:

  • returns the named thing.

Returns:

  • void

See Also:

Since:

  • 0.0.1



97
98
99
100
# File 'lib/power_converter.rb', line 97

def define_conversion_for(named_conversion, &converter)
  @defined_conversions ||= {}
  @defined_conversions[named_conversion.to_s] = converter
end

.defined_converter_namesArray

A convenience method for seeing the names of all converters that have been defined.

Returns:

  • (Array)

    of the defined converter’s names

Since:

  • 0.0.1



232
233
234
# File 'lib/power_converter.rb', line 232

def defined_converter_names
  defined_conversions.keys + aliased_conversions.keys
end

.module_for(named_conversion) ⇒ Module

TODO:

Allow for the inclusion of multiple power converter named types.

Note:

This does not allow for the robustness of the .convert method. I’m wondering about its ongoing value.

The means for mixing in a private conversion method; Perhaps as policy you don’t want to expose the public conversion method but instead prefer to leverage private methods.

Examples:

class Foo
  attr_accessor :bar
  include PowerConverter.module_for(:boolean)
  def bar_as_boolean
    convert_to_boolean(@bar)
  end
end

Parameters:

  • named_conversion (String, Symbol)

    the name of the conversion that you are requesting be wrapped in a conversion module.

Returns:

  • (Module)

    a conversion module to use for mixing in behavior

Since:

  • 0.0.1



193
194
195
196
197
198
199
# File 'lib/power_converter.rb', line 193

def module_for(named_conversion)
  Module.new do
    extend Forwardable
    def_delegator PowerConverter, "#{CONVERSION_METHOD_PREFIX}#{named_conversion}"
    private "#{CONVERSION_METHOD_PREFIX}#{named_conversion}"
  end
end