Module: Hanami::Utils::Kernel

Defined in:
lib/hanami/utils/kernel.rb

Overview

Kernel utilities rubocop:disable Style/MethodName rubocop:disable Metrics/ModuleLength

Since:

  • 0.1.1

Constant Summary collapse

NUMERIC_MATCHER =

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

Matcher for numeric values

See Also:

Since:

  • 0.3.3

%r{\A([\d\/\.\+iE]+|NaN|Infinity)\z}
BOOLEAN_FALSE_STRING =

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

Since:

  • 0.8.0

'0'.freeze
BOOLEAN_TRUE_INTEGER =

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

Since:

  • 0.8.0

1

Class Method Summary collapse

Class Method Details

.Array(arg) ⇒ Array

Coerces the argument to be an Array.

It’s similar to Ruby’s Kernel.Array, but it applies further transformations:

* flatten
* compact
* uniq

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Array(nil)              # => []
Hanami::Utils::Kernel.Array(true)             # => [true]
Hanami::Utils::Kernel.Array(false)            # => [false]
Hanami::Utils::Kernel.Array(1)                # => [1]
Hanami::Utils::Kernel.Array([1])              # => [1]
Hanami::Utils::Kernel.Array([1, [2]])         # => [1,2]
Hanami::Utils::Kernel.Array([1, [2, nil]])    # => [1,2]
Hanami::Utils::Kernel.Array([1, [2, nil, 1]]) # => [1,2]

Array Interface

require 'hanami/utils/kernel'

ResultSet = Struct.new(:records) do
  def to_a
    records.to_a.sort
  end
end

Response = Struct.new(:status, :headers, :body) do
  def to_ary
    [status, headers, body]
  end
end

set = ResultSet.new([2,1,3])
Hanami::Utils::Kernel.Array(set)              # => [1,2,3]

response = Response.new(200, {}, 'hello')
Hanami::Utils::Kernel.Array(response)         # => [200, {}, "hello"]

Parameters:

  • arg (Object)

    the input

Returns:

  • (Array)

    the result of the coercion

See Also:

Since:

  • 0.1.1



95
96
97
98
99
100
101
# File 'lib/hanami/utils/kernel.rb', line 95

def self.Array(arg)
  super(arg).dup.tap do |a|
    a.flatten!
    a.compact!
    a.uniq!
  end
end

.BigDecimal(arg) ⇒ BigDecimal

Coerces the argument to be a BigDecimal.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.BigDecimal(1)                        # => 1
Hanami::Utils::Kernel.BigDecimal(1.2)                      # => 1
Hanami::Utils::Kernel.BigDecimal(011)                      # => 9
Hanami::Utils::Kernel.BigDecimal(0xf5)                     # => 245
Hanami::Utils::Kernel.BigDecimal("1")                      # => 1
Hanami::Utils::Kernel.BigDecimal(Rational(0.3))            # => 0.3
Hanami::Utils::Kernel.BigDecimal(Complex(0.3))             # => 0.3
Hanami::Utils::Kernel.BigDecimal(BigDecimal.new(12.00001)) # => 12.00001
Hanami::Utils::Kernel.BigDecimal(176605528590345446089)
  # => 176605528590345446089

BigDecimal Interface

require 'hanami/utils/kernel'

UltimateAnswer = Struct.new(:question) do
  def to_d
    BigDecimal.new(42)
  end
end

answer = UltimateAnswer.new('The Ultimate Question of Life')
Hanami::Utils::Kernel.BigDecimal(answer)
  # => #<BigDecimal:7fabfd148588,'0.42E2',9(27)>

Unchecked exceptions

require 'hanami/utils/kernel'

# When nil
input = nil
Hanami::Utils::Kernel.BigDecimal(nil) # => TypeError

# When true
input = true
Hanami::Utils::Kernel.BigDecimal(input) # => TypeError

# When false
input = false
Hanami::Utils::Kernel.BigDecimal(input) # => TypeError

# When Date
input = Date.today
Hanami::Utils::Kernel.BigDecimal(input) # => TypeError

# When DateTime
input = DateTime.now
Hanami::Utils::Kernel.BigDecimal(input) # => TypeError

# When Time
input = Time.now
Hanami::Utils::Kernel.BigDecimal(input) # => TypeError

# String that doesn't represent a big decimal
input = 'hello'
Hanami::Utils::Kernel.BigDecimal(input) # => TypeError

# Missing #respond_to?
input = BasicObject.new
Hanami::Utils::Kernel.BigDecimal(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

Raises:

  • (TypeError)

    if the argument can’t be coerced

See Also:

Since:

  • 0.3.0



421
422
423
424
425
426
427
428
429
430
431
432
# File 'lib/hanami/utils/kernel.rb', line 421

def self.BigDecimal(arg)
  case arg
  when Numeric
    BigDecimal(arg.to_s)
  when ->(a) { a.respond_to?(:to_d) }
    arg.to_d
  else
    BigDecimal.new(arg)
  end
rescue NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into BigDecimal"
end

.Boolean(arg) ⇒ true, false

Coerces the argument to be a Boolean.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Boolean(nil)                      # => false
Hanami::Utils::Kernel.Boolean(0)                        # => false
Hanami::Utils::Kernel.Boolean(1)                        # => true
Hanami::Utils::Kernel.Boolean('0')                      # => false
Hanami::Utils::Kernel.Boolean('1')                      # => true
Hanami::Utils::Kernel.Boolean(Object.new)               # => true

Boolean Interface

require 'hanami/utils/kernel'

Answer = Struct.new(:answer) do
  def to_bool
    case answer
    when 'yes' then true
    else false
    end
  end
end

answer = Answer.new('yes')
Hanami::Utils::Kernel.Boolean(answer) # => true

Unchecked Exceptions

require 'hanami/utils/kernel'

# Missing #respond_to?
input = BasicObject.new
Hanami::Utils::Kernel.Boolean(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

  • (true, false)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

Since:

  • 0.1.1



895
896
897
898
899
900
901
902
903
904
905
906
907
908
# File 'lib/hanami/utils/kernel.rb', line 895

def self.Boolean(arg) # rubocop:disable Metrics/MethodLength
  case arg
  when Numeric
    arg.to_i == BOOLEAN_TRUE_INTEGER
  when ::String, Utils::String, BOOLEAN_FALSE_STRING
    Boolean(arg.to_i)
  when ->(a) { a.respond_to?(:to_bool) }
    arg.to_bool
  else
    !!arg
  end
rescue NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Boolean"
end

.Date(arg) ⇒ Date

Coerces the argument to be a Date.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Date(Date.today)
  # => #<Date: 2014-04-17 ((2456765j,0s,0n),+0s,2299161j)>

Hanami::Utils::Kernel.Date(DateTime.now)
  # => #<Date: 2014-04-17 ((2456765j,0s,0n),+0s,2299161j)>

Hanami::Utils::Kernel.Date(Time.now)
  # => #<Date: 2014-04-17 ((2456765j,0s,0n),+0s,2299161j)>

Hanami::Utils::Kernel.Date('2014-04-17')
  # => #<Date: 2014-04-17 ((2456765j,0s,0n),+0s,2299161j)>

Hanami::Utils::Kernel.Date('2014-04-17 22:37:15')
  # => #<Date: 2014-04-17 ((2456765j,0s,0n),+0s,2299161j)>

Date Interface

require 'hanami/utils/kernel'

class Christmas
  def to_date
    Date.parse('Dec, 25')
  end
end

Hanami::Utils::Kernel.Date(Christmas.new)
  # => #<Date: 2014-12-25 ((2457017j,0s,0n),+0s,2299161j)>

Unchecked Exceptions

require 'hanami/utils/kernel'

# nil
input = nil
Hanami::Utils::Kernel.Date(input) # => TypeError

# Missing #respond_to?
input = BasicObject.new
Hanami::Utils::Kernel.Date(input) # => TypeError

# Missing #to_s?
input = BasicObject.new
Hanami::Utils::Kernel.Date(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

  • (Date)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

Since:

  • 0.1.1



711
712
713
714
715
716
717
718
719
# File 'lib/hanami/utils/kernel.rb', line 711

def self.Date(arg)
  if arg.respond_to?(:to_date)
    arg.to_date
  else
    Date.parse(arg.to_s)
  end
rescue ArgumentError, NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Date"
end

.DateTime(arg) ⇒ DateTime

Coerces the argument to be a DateTime.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.DateTime(3483943)
  # => Time.at(3483943).to_datetime #<DateTime: 1970-02-10T08:45:43+01:00 ((2440628j,27943s,0n),+3600s,2299161j)>

Hanami::Utils::Kernel.DateTime(DateTime.now)
  # => #<DateTime: 2014-04-18T09:33:49+02:00 ((2456766j,27229s,690849000n),+7200s,2299161j)>

Hanami::Utils::Kernel.DateTime(Date.today)
  # => #<DateTime: 2014-04-18T00:00:00+00:00 ((2456766j,0s,0n),+0s,2299161j)>

Hanami::Utils::Kernel.Date(Time.now)
  # => #<DateTime: 2014-04-18T09:34:49+02:00 ((2456766j,27289s,832907000n),+7200s,2299161j)>

Hanami::Utils::Kernel.DateTime('2014-04-18')
  # => #<DateTime: 2014-04-18T00:00:00+00:00 ((2456766j,0s,0n),+0s,2299161j)>

Hanami::Utils::Kernel.DateTime('2014-04-18 09:35:42')
  # => #<DateTime: 2014-04-18T09:35:42+00:00 ((2456766j,34542s,0n),+0s,2299161j)>

DateTime Interface

require 'hanami/utils/kernel'

class NewYearEve
  def to_datetime
    DateTime.parse('Jan, 1')
  end
end

Hanami::Utils::Kernel.Date(NewYearEve.new)
  # => #<DateTime: 2014-01-01T00:00:00+00:00 ((2456659j,0s,0n),+0s,2299161j)>

Unchecked Exceptions

require 'hanami/utils/kernel'

# When nil
input = nil
Hanami::Utils::Kernel.DateTime(input) # => TypeError

# Missing #respond_to?
input = BasicObject.new
Hanami::Utils::Kernel.DateTime(input) # => TypeError

# Missing #to_s?
input = BasicObject.new
Hanami::Utils::Kernel.DateTime(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

  • (DateTime)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

Since:

  • 0.1.1



778
779
780
781
782
783
784
785
786
787
# File 'lib/hanami/utils/kernel.rb', line 778

def self.DateTime(arg)
  case arg
  when ->(a) { a.respond_to?(:to_datetime) } then arg.to_datetime
  when Numeric then DateTime(Time.at(arg))
  else
    DateTime.parse(arg.to_s)
  end
rescue ArgumentError, NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into DateTime"
end

.Float(arg) ⇒ Float

Coerces the argument to be a Float.

It’s similar to Ruby’s Kernel.Float, but it doesn’t stop at the first error and raise an exception only when the argument can’t be coerced.

Examples:

Basic Usage

require 'bigdecimal'
require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Float(1)                        # => 1.0
Hanami::Utils::Kernel.Float(1.2)                      # => 1.2
Hanami::Utils::Kernel.Float(011)                      # => 9.0
Hanami::Utils::Kernel.Float(0xf5)                     # => 245.0
Hanami::Utils::Kernel.Float("1")                      # => 1.0
Hanami::Utils::Kernel.Float(Rational(0.3))            # => 0.3
Hanami::Utils::Kernel.Float(Complex(0.3))             # => 0.3
Hanami::Utils::Kernel.Float(BigDecimal.new(12.00001)) # => 12.00001
Hanami::Utils::Kernel.Float(176605528590345446089)
  # => 176605528590345446089.0

Hanami::Utils::Kernel.Float(Time.now) # => 397750945.515169

Float Interface

require 'hanami/utils/kernel'

class Pi
  def to_f
    3.14
  end
end

pi = Pi.new
Hanami::Utils::Kernel.Float(pi) # => 3.14

Error Handling

require 'bigdecimal'
require 'hanami/utils/kernel'

# nil
Kernel.Float(nil)               # => TypeError
Hanami::Utils::Kernel.Float(nil) # => 0.0

# float represented as a string
Kernel.Float("23.4")               # => TypeError
Hanami::Utils::Kernel.Float("23.4") # => 23.4

# rational represented as a string
Kernel.Float("2/3")               # => TypeError
Hanami::Utils::Kernel.Float("2/3") # => 2.0

# complex represented as a string
Kernel.Float("2.5/1")               # => TypeError
Hanami::Utils::Kernel.Float("2.5/1") # => 2.5

# bigdecimal infinity
input = BigDecimal.new("Infinity")
Hanami::Utils::Kernel.Float(input) # => Infinity

# bigdecimal NaN
input = BigDecimal.new("NaN")
Hanami::Utils::Kernel.Float(input) # => NaN

Unchecked Exceptions

require 'date'
require 'bigdecimal'
require 'hanami/utils/kernel'

# Missing #to_f
input = OpenStruct.new(color: 'purple')
Hanami::Utils::Kernel.Float(input) # => TypeError

# When true
input = true
Hanami::Utils::Kernel.Float(input) # => TypeError

# When false
input = false
Hanami::Utils::Kernel.Float(input) # => TypeError

# When Date
input = Date.today
Hanami::Utils::Kernel.Float(input) # => TypeError

# When DateTime
input = DateTime.now
Hanami::Utils::Kernel.Float(input) # => TypeError

# Missing #nil?
input = BasicObject.new
Hanami::Utils::Kernel.Float(input) # => TypeError

# String that doesn't represent a float
input = 'hello'
Hanami::Utils::Kernel.Float(input) # => TypeError

# big rational
input = Rational(-8) ** Rational(1, 3)
Hanami::Utils::Kernel.Float(input) # => TypeError

# big complex represented as a string
input = Complex(2, 3)
Hanami::Utils::Kernel.Float(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

  • (Float)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

See Also:

Since:

  • 0.1.1



546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
# File 'lib/hanami/utils/kernel.rb', line 546

def self.Float(arg) # rubocop:disable Metrics/MethodLength
  super(arg)
rescue ArgumentError, TypeError
  begin
    case arg
    when NilClass, ->(a) { a.respond_to?(:to_f) && numeric?(a) }
      arg.to_f
    else
      raise TypeError.new "can't convert #{inspect_type_error(arg)}into Float"
    end
  rescue NoMethodError
    raise TypeError.new "can't convert #{inspect_type_error(arg)}into Float"
  end
rescue RangeError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Float"
end

.Hash(arg) ⇒ Hash

Coerces the argument to be a Hash.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Hash(nil)                 # => {}
Hanami::Utils::Kernel.Hash({a: 1})              # => { :a => 1 }
Hanami::Utils::Kernel.Hash([[:a, 1]])           # => { :a => 1 }
Hanami::Utils::Kernel.Hash(Set.new([[:a, 1]]))  # => { :a => 1 }

Hash Interface

require 'hanami/utils/kernel'

Room = Class.new do
  def initialize(*args)
    @args = args
  end

  def to_h
    Hash[*@args]
  end
end

Record = Class.new do
  def initialize(attributes = {})
    @attributes = attributes
  end

  def to_hash
    @attributes
  end
end

room = Room.new(:key, 123456)
Hanami::Utils::Kernel.Hash(room)        # => { :key => 123456 }

record = Record.new(name: 'L')
Hanami::Utils::Kernel.Hash(record)      # => { :name => "L" }

Unchecked Exceptions

require 'hanami/utils/kernel'

input = BasicObject.new
Hanami::Utils::Kernel.Hash(input) # => TypeError

Parameters:

  • arg (Object)

    the input

Returns:

  • (Hash)

    the result of the coercion

Raises:

  • (TypeError)

    if arg can’t be coerced

See Also:

Since:

  • 0.1.1



214
215
216
217
218
219
220
221
222
# File 'lib/hanami/utils/kernel.rb', line 214

def self.Hash(arg)
  if arg.respond_to?(:to_h)
    arg.to_h
  else
    super(arg)
  end
rescue NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Hash"
end

.inspect_type_error(arg) ⇒ Object

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.

Returns the most useful type error possible

If the object does not respond_to?(:inspect), we return the class, else we return nil. In all cases, this method is tightly bound to callers, as this method appends the required space to make the error message look good.

Since:

  • 0.4.3



1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
# File 'lib/hanami/utils/kernel.rb', line 1040

def self.inspect_type_error(arg)
  (arg.respond_to?(:inspect) ? arg.inspect : arg.to_s) << ' '
rescue NoMethodError => _
  # missing the #respond_to? method, fall back to returning the class' name
  begin
    arg.class.name << ' instance '
  rescue NoMethodError
    # missing the #class method, can't fall back to anything better than nothing
    # Callers will have to guess from their code
    nil
  end
end

.Integer(arg) ⇒ Fixnum

Coerces the argument to be an Integer.

It’s similar to Ruby’s Kernel.Integer, but it doesn’t stop at the first error and raise an exception only when the argument can’t be coerced.

Examples:

Basic Usage

require 'bigdecimal'
require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Integer(1)                        # => 1
Hanami::Utils::Kernel.Integer(1.2)                      # => 1
Hanami::Utils::Kernel.Integer(011)                      # => 9
Hanami::Utils::Kernel.Integer(0xf5)                     # => 245
Hanami::Utils::Kernel.Integer("1")                      # => 1
Hanami::Utils::Kernel.Integer(Rational(0.3))            # => 0
Hanami::Utils::Kernel.Integer(Complex(0.3))             # => 0
Hanami::Utils::Kernel.Integer(BigDecimal.new(12.00001)) # => 12
Hanami::Utils::Kernel.Integer(176605528590345446089)
  # => 176605528590345446089

Hanami::Utils::Kernel.Integer(Time.now)                 # => 1396947161

Integer Interface

require 'hanami/utils/kernel'

UltimateAnswer = Struct.new(:question) do
  def to_int
    42
  end
end

answer = UltimateAnswer.new('The Ultimate Question of Life')
Hanami::Utils::Kernel.Integer(answer) # => 42

Error Handling

require 'hanami/utils/kernel'

# nil
Kernel.Integer(nil)               # => TypeError
Hanami::Utils::Kernel.Integer(nil) # => 0

# float represented as a string
Kernel.Integer("23.4")               # => TypeError
Hanami::Utils::Kernel.Integer("23.4") # => 23

# rational represented as a string
Kernel.Integer("2/3")               # => TypeError
Hanami::Utils::Kernel.Integer("2/3") # => 2

# complex represented as a string
Kernel.Integer("2.5/1")               # => TypeError
Hanami::Utils::Kernel.Integer("2.5/1") # => 2

Unchecked Exceptions

require 'date'
require 'bigdecimal'
require 'hanami/utils/kernel'

# Missing #to_int and #to_i
input = OpenStruct.new(color: 'purple')
Hanami::Utils::Kernel.Integer(input) # => TypeError

# String that doesn't represent an integer
input = 'hello'
Hanami::Utils::Kernel.Integer(input) # => TypeError

# When true
input = true
Hanami::Utils::Kernel.Integer(input) # => TypeError

# When false
input = false
Hanami::Utils::Kernel.Integer(input) # => TypeError

# When Date
input = Date.today
Hanami::Utils::Kernel.Integer(input) # => TypeError

# When DateTime
input = DateTime.now
Hanami::Utils::Kernel.Integer(input) # => TypeError

# bigdecimal infinity
input = BigDecimal.new("Infinity")
Hanami::Utils::Kernel.Integer(input) # => TypeError

# bigdecimal NaN
input = BigDecimal.new("NaN")
Hanami::Utils::Kernel.Integer(input) # => TypeError

# big rational
input = Rational(-8) ** Rational(1, 3)
Hanami::Utils::Kernel.Integer(input) # => TypeError

# big complex represented as a string
input = Complex(2, 3)
Hanami::Utils::Kernel.Integer(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

  • (Fixnum)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

See Also:

Since:

  • 0.1.1



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/hanami/utils/kernel.rb', line 331

def self.Integer(arg) # rubocop:disable Metrics/MethodLength
  super(arg)
rescue ArgumentError, TypeError, NoMethodError
  begin
    case arg
    when NilClass, ->(a) { a.respond_to?(:to_i) && numeric?(a) }
      arg.to_i
    else
      raise TypeError.new "can't convert #{inspect_type_error(arg)}into Integer"
    end
  rescue NoMethodError
    raise TypeError.new "can't convert #{inspect_type_error(arg)}into Integer"
  end
rescue RangeError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Integer"
end

.numeric?(arg) ⇒ TrueClass, FalseClass

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.

Check if the given argument is a string representation of a number

Parameters:

  • arg (Object)

    the input

Returns:

  • (TrueClass, FalseClass)

Since:

  • 0.8.0



1028
1029
1030
# File 'lib/hanami/utils/kernel.rb', line 1028

def self.numeric?(arg)
  !(arg.to_s =~ NUMERIC_MATCHER).nil?
end

.Pathname(arg) ⇒ Pathname

Coerces the argument to be a Pathname.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Pathname(Pathname.new('/path/to')) # => #<Pathname:/path/to>
Hanami::Utils::Kernel.Pathname('/path/to')               # => #<Pathname:/path/to>

Pathname Interface

require 'hanami/utils/kernel'

class HomePath
  def to_pathname
    Pathname.new Dir.home
  end
end

Hanami::Utils::Kernel.Pathname(HomePath.new) # => #<Pathname:/Users/luca>

String Interface

require 'hanami/utils/kernel'

class RootPath
  def to_str
    '/'
  end
end

Hanami::Utils::Kernel.Pathname(RootPath.new) # => #<Pathname:/>

Unchecked Exceptions

require 'hanami/utils/kernel'

# When nil
input = nil
Hanami::Utils::Kernel.Pathname(input) # => TypeError

# Missing #respond_to?
input = BasicObject.new
Hanami::Utils::Kernel.Pathname(input) # => TypeError

Parameters:

  • arg (#to_pathname, #to_str)

    the argument

Returns:

  • (Pathname)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

Since:

  • 0.1.2



958
959
960
961
962
963
964
965
966
# File 'lib/hanami/utils/kernel.rb', line 958

def self.Pathname(arg)
  case arg
  when ->(a) { a.respond_to?(:to_pathname) } then arg.to_pathname
  else
    super
  end
rescue NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Pathname"
end

.Set(arg) ⇒ Set

Coerces the argument to be a Set.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Set(nil)              # => #<Set: {}>
Hanami::Utils::Kernel.Set(true)             # => #<Set: {true}>
Hanami::Utils::Kernel.Set(false)            # => #<Set: {false}>
Hanami::Utils::Kernel.Set(1)                # => #<Set: {1}>
Hanami::Utils::Kernel.Set([1])              # => #<Set: {1}>
Hanami::Utils::Kernel.Set([1, 1])           # => #<Set: {1}>
Hanami::Utils::Kernel.Set([1, [2]])         # => #<Set: {1, [2]}>
Hanami::Utils::Kernel.Set([1, [2, nil]])    # => #<Set: {1, [2, nil]}>
Hanami::Utils::Kernel.Set({a: 1})           # => #<Set: {[:a, 1]}>

Set Interface

require 'securerandom'
require 'hanami/utils/kernel'

UuidSet = Class.new do
  def initialize(*uuids)
    @uuids = uuids
  end

  def to_set
    Set.new.tap do |set|
      @uuids.each {|uuid| set.add(uuid) }
    end
  end
end

uuids = UuidSet.new(SecureRandom.uuid)
Hanami::Utils::Kernel.Set(uuids)
  # => #<Set: {"daa798b4-630c-4e11-b29d-92f0b1c7d075"}>

Unchecked Exceptions

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Set(BasicObject.new) # => TypeError

Parameters:

  • arg (Object)

    the input

Returns:

  • (Set)

    the result of the coercion

Raises:

  • (TypeError)

    if arg doesn’t implement #respond_to?

Since:

  • 0.1.1



150
151
152
153
154
155
156
157
158
# File 'lib/hanami/utils/kernel.rb', line 150

def self.Set(arg)
  if arg.respond_to?(:to_set)
    arg.to_set
  else
    Set.new(::Kernel.Array(arg))
  end
rescue NoMethodError
  raise TypeError.new("can't convert #{inspect_type_error(arg)}into Set")
end

.String(arg) ⇒ String

Coerces the argument to be a String.

Identical behavior of Ruby’s Kernel.Array, still here because we want to keep the interface consistent

Examples:

Basic Usage

require 'date'
require 'bigdecimal'
require 'hanami/utils/kernel'

Hanami::Utils::Kernel.String('')                            # => ""
Hanami::Utils::Kernel.String('ciao')                        # => "ciao"

Hanami::Utils::Kernel.String(true)                          # => "true"
Hanami::Utils::Kernel.String(false)                         # => "false"

Hanami::Utils::Kernel.String(:hanami)                        # => "hanami"

Hanami::Utils::Kernel.String(Picture)                       # => "Picture" # class
Hanami::Utils::Kernel.String(Hanami)                         # => "Hanami" # module

Hanami::Utils::Kernel.String([])                            # => "[]"
Hanami::Utils::Kernel.String([1,2,3])                       # => "[1, 2, 3]"
Hanami::Utils::Kernel.String(%w[a b c])                     # => "[\"a\", \"b\", \"c\"]"

Hanami::Utils::Kernel.String({})                            # => "{}"
Hanami::Utils::Kernel.String({a: 1, 'b' => 'c'})            # => "{:a=>1, \"b\"=>\"c\"}"

Hanami::Utils::Kernel.String(Date.today)                    # => "2014-04-11"
Hanami::Utils::Kernel.String(DateTime.now)                  # => "2014-04-11T10:15:06+02:00"
Hanami::Utils::Kernel.String(Time.now)                      # => "2014-04-11 10:15:53 +0200"

Hanami::Utils::Kernel.String(1)                             # => "1"
Hanami::Utils::Kernel.String(3.14)                          # => "3.14"
Hanami::Utils::Kernel.String(013)                           # => "11"
Hanami::Utils::Kernel.String(0xc0ff33)                      # => "12648243"

Hanami::Utils::Kernel.String(Rational(-22))                 # => "-22/1"
Hanami::Utils::Kernel.String(Complex(11, 2))                # => "11+2i"
Hanami::Utils::Kernel.String(BigDecimal.new(7944.2343, 10)) # => "0.79442343E4"
Hanami::Utils::Kernel.String(BigDecimal.new('Infinity'))    # => "Infinity"
Hanami::Utils::Kernel.String(BigDecimal.new('NaN'))         # => "Infinity"

String interface

require 'hanami/utils/kernel'

SimpleObject = Class.new(BasicObject) do
  def to_s
    'simple object'
  end
end

Isbn = Struct.new(:code) do
  def to_str
    code.to_s
  end
end

simple = SimpleObject.new
isbn   = Isbn.new(123)

Hanami::Utils::Kernel.String(simple) # => "simple object"
Hanami::Utils::Kernel.String(isbn)   # => "123"

Comparison with Ruby

require 'hanami/utils/kernel'

# nil
Kernel.String(nil)               # => ""
Hanami::Utils::Kernel.String(nil) # => ""

Unchecked Exceptions

require 'hanami/utils/kernel'

# Missing #to_s or #to_str
input = BaseObject.new
Hanami::Utils::Kernel.String(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

  • (String)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

See Also:

Since:

  • 0.1.1



650
651
652
653
654
655
# File 'lib/hanami/utils/kernel.rb', line 650

def self.String(arg)
  arg = arg.to_str if arg.respond_to?(:to_str)
  super(arg)
rescue NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into String"
end

.Symbol(arg) ⇒ Symbol

Coerces the argument to be a Symbol.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Symbol(:hello)  # => :hello
Hanami::Utils::Kernel.Symbol('hello') # => :hello

Symbol Interface

require 'hanami/utils/kernel'

class StatusSymbol
  def to_sym
    :success
  end
end

Hanami::Utils::Kernel.Symbol(StatusSymbol.new) # => :success

Unchecked Exceptions

require 'hanami/utils/kernel'

# When nil
input = nil
Hanami::Utils::Kernel.Symbol(input) # => TypeError

# When empty string
input = ''
Hanami::Utils::Kernel.Symbol(input) # => TypeError

# Missing #respond_to?
input = BasicObject.new
Hanami::Utils::Kernel.Symbol(input) # => TypeError

Parameters:

  • arg (#to_sym)

    the argument

Returns:

  • (Symbol)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

Since:

  • 0.2.0



1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
# File 'lib/hanami/utils/kernel.rb', line 1009

def self.Symbol(arg)
  case arg
  when '' then raise TypeError.new "can't convert #{inspect_type_error(arg)}into Symbol"
  when ->(a) { a.respond_to?(:to_sym) } then arg.to_sym
  else
    raise TypeError.new "can't convert #{inspect_type_error(arg)}into Symbol"
  end
rescue NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Symbol"
end

.Time(arg) ⇒ Time

Coerces the argument to be a Time.

Examples:

Basic Usage

require 'hanami/utils/kernel'

Hanami::Utils::Kernel.Time(Time.now)
  # => 2014-04-18 15:56:39 +0200

Hanami::Utils::Kernel.Time(DateTime.now)
  # => 2014-04-18 15:56:39 +0200

Hanami::Utils::Kernel.Time(Date.today)
  # => 2014-04-18 00:00:00 +0200

Hanami::Utils::Kernel.Time('2014-04-18')
  # => 2014-04-18 00:00:00 +0200

Hanami::Utils::Kernel.Time('2014-04-18 15:58:02')
  # => 2014-04-18 15:58:02 +0200

Time Interface

require 'hanami/utils/kernel'

class Epoch
  def to_time
    Time.at(0)
  end
end

Hanami::Utils::Kernel.Time(Epoch.new)
  # => 1970-01-01 01:00:00 +0100

Unchecked Exceptions

require 'hanami/utils/kernel'

# When nil
input = nil
Hanami::Utils::Kernel.Time(input) # => TypeError

# Missing #respond_to?
input = BasicObject.new
Hanami::Utils::Kernel.Time(input) # => TypeError

# Missing #to_s?
input = BasicObject.new
Hanami::Utils::Kernel.Time(input) # => TypeError

Parameters:

  • arg (Object)

    the argument

Returns:

  • (Time)

    the result of the coercion

Raises:

  • (TypeError)

    if the argument can’t be coerced

Since:

  • 0.1.1



843
844
845
846
847
848
849
850
851
852
# File 'lib/hanami/utils/kernel.rb', line 843

def self.Time(arg)
  case arg
  when ->(a) { a.respond_to?(:to_time) } then arg.to_time
  when Numeric then Time.at(arg)
  else
    Time.parse(arg.to_s)
  end
rescue ArgumentError, NoMethodError
  raise TypeError.new "can't convert #{inspect_type_error(arg)}into Time"
end