Module: Hanami::Utils::Kernel

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

Overview

Kernel utilities

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

/\A([\d\/\.\+iE]+|NaN|Infinity)\z/.freeze

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



81
82
83
84
85
86
87
# File 'lib/hanami/utils/kernel.rb', line 81

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



407
408
409
410
411
412
413
414
415
416
417
418
419
# File 'lib/hanami/utils/kernel.rb', line 407

def self.BigDecimal(arg)
  case arg
  when ->(a) { a.respond_to?(:to_d) } then arg.to_d
  when Float, Complex, Rational
    BigDecimal(arg.to_s)
  when ->(a) { a.to_s.match(NUMERIC_MATCHER) }
    BigDecimal.new(arg)
  else
    raise TypeError.new "can't convert #{inspect_type_error(arg)}into BigDecimal"
  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



882
883
884
885
886
887
888
889
890
891
892
# File 'lib/hanami/utils/kernel.rb', line 882

def self.Boolean(arg)
  case arg
  when Numeric     then arg > 0 && arg <= 1
  when String, '0' then Boolean(arg.to_i)
  when ->(a) { a.respond_to?(:to_bool) } then 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



698
699
700
701
702
703
704
705
706
# File 'lib/hanami/utils/kernel.rb', line 698

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



765
766
767
768
769
770
771
772
773
774
# File 'lib/hanami/utils/kernel.rb', line 765

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



533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
# File 'lib/hanami/utils/kernel.rb', line 533

def self.Float(arg)
  super(arg)
rescue ArgumentError, TypeError
  begin
    case arg
    when NilClass, ->(a) { a.respond_to?(:to_f) && a.to_s.match(NUMERIC_MATCHER) }
      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



200
201
202
203
204
205
206
207
208
# File 'lib/hanami/utils/kernel.rb', line 200

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



1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
# File 'lib/hanami/utils/kernel.rb', line 1012

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



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/hanami/utils/kernel.rb', line 317

def self.Integer(arg)
  super(arg)
rescue ArgumentError, TypeError, NoMethodError
  begin
    case arg
    when NilClass, ->(a) { a.respond_to?(:to_i) && a.to_s.match(NUMERIC_MATCHER) }
      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

.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



942
943
944
945
946
947
948
949
950
# File 'lib/hanami/utils/kernel.rb', line 942

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



136
137
138
139
140
141
142
143
144
# File 'lib/hanami/utils/kernel.rb', line 136

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



637
638
639
640
641
642
# File 'lib/hanami/utils/kernel.rb', line 637

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



993
994
995
996
997
998
999
1000
1001
1002
# File 'lib/hanami/utils/kernel.rb', line 993

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



830
831
832
833
834
835
836
837
838
839
# File 'lib/hanami/utils/kernel.rb', line 830

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