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
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:

  • x.x.x

'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:

  • x.x.x

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



90
91
92
93
94
95
96
# File 'lib/hanami/utils/kernel.rb', line 90

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

  • precision (Keyword)

    precision for Rational objects (Only JRuby).

Returns:

Raises:

  • (TypeError)

    if the argument can’t be coerced

See Also:

Since:

  • 0.3.0



417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/hanami/utils/kernel.rb', line 417

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



891
892
893
894
895
896
897
898
899
900
901
902
903
904
# File 'lib/hanami/utils/kernel.rb', line 891

def self.Boolean(arg)
  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



707
708
709
710
711
712
713
714
715
# File 'lib/hanami/utils/kernel.rb', line 707

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



774
775
776
777
778
779
780
781
782
783
# File 'lib/hanami/utils/kernel.rb', line 774

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



542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
# File 'lib/hanami/utils/kernel.rb', line 542

def self.Float(arg)
  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



209
210
211
212
213
214
215
216
217
# File 'lib/hanami/utils/kernel.rb', line 209

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



1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
# File 'lib/hanami/utils/kernel.rb', line 1036

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



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/hanami/utils/kernel.rb', line 326

def self.Integer(arg)
  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:

  • x.x.x



1024
1025
1026
# File 'lib/hanami/utils/kernel.rb', line 1024

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



954
955
956
957
958
959
960
961
962
# File 'lib/hanami/utils/kernel.rb', line 954

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



145
146
147
148
149
150
151
152
153
# File 'lib/hanami/utils/kernel.rb', line 145

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



646
647
648
649
650
651
# File 'lib/hanami/utils/kernel.rb', line 646

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



1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
# File 'lib/hanami/utils/kernel.rb', line 1005

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



839
840
841
842
843
844
845
846
847
848
# File 'lib/hanami/utils/kernel.rb', line 839

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