Module: Ukiryu::Utils

Defined in:
lib/ukiryu/utils.rb

Overview

Utils - Shared utility methods for Ukiryu

Provides common utilities used throughout the codebase, including hash transformation, file operations, and type coercion.

Usage

require 'ukiryu/utils'

# Symbolize hash keys recursively
Ukiryu::Utils.symbolize_keys({ 'foo' => { 'bar' => 'baz' } })
# => { foo: { bar: 'baz' } }

Class Method Summary collapse

Class Method Details

.cache_key(*args) ⇒ String

Generate a cache key from arguments

Creates a deterministic string key from various input types.

Parameters:

  • args (Array)

    the arguments to create key from

Returns:

  • (String)

    cache key string



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/ukiryu/utils.rb', line 153

def cache_key(*args)
  args.map do |arg|
    case arg
    when nil
      'nil'
    when true
      'true'
    when false
      'false'
    when Array
      "[#{arg.map { |a| cache_key(a) }.join(',')}]"
    when Hash
      "{#{arg.map { |k, v| "#{cache_key(k)}:#{cache_key(v)}" }.join(',')}}"
    when Symbol
      ":#{arg}"
    when String
      arg.include?(' ') || arg.include?(':') ? arg.inspect : arg
    else
      arg.to_s
    end
  end.join(':')
end

.clear_memo_cacheObject

Clear the memoization cache



195
196
197
# File 'lib/ukiryu/utils.rb', line 195

def clear_memo_cache
  @memo_cache = nil
end

.coerce(value, type) ⇒ Object

Coerce a value to a specific type

Examples:

Utils.coerce('42', :integer)  # => 42
Utils.coerce('true', :boolean) # => true

Parameters:

  • value (Object)

    the value to coerce

  • type (Symbol)

    the target type (:string, :integer, :float, :boolean, :symbol, :array)

Returns:

  • (Object)

    the coerced value



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/ukiryu/utils.rb', line 88

def coerce(value, type)
  return value if value.is_a?(type) && type != :array

  case type
  when :string
    value.to_s
  when :integer
    value.to_i
  when :float
    value.to_f
  when :boolean
    coerce_boolean(value)
  when :symbol
    value.to_s.to_sym
  when :array
    Array(value)
  else
    value
  end
end

.deep_freeze(hash) ⇒ Hash

Deep freeze a hash and all nested values

Makes a hash immutable by freezing it and all nested structures.

Parameters:

  • hash (Hash)

    the hash to freeze

Returns:

  • (Hash)

    frozen hash



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ukiryu/utils.rb', line 51

def deep_freeze(hash)
  hash.each do |key, value|
    if value.is_a?(Hash)
      deep_freeze(value)
    elsif value.is_a?(Array)
      value.each(&:freeze)
    end
    key.freeze
  end
  hash.freeze
end

.format_path(path, shell = :unix) ⇒ String

Format a path for the current shell

Parameters:

  • path (String)

    the path to format

  • shell (Symbol) (defaults to: :unix)

    the shell type

Returns:

  • (String)

    formatted path



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/ukiryu/utils.rb', line 134

def format_path(path, shell = :unix)
  path = path.to_s
  case shell
  when :unix
    path.gsub('\\', '/')
  when :windows
    path.gsub('/', '\\')
  else
    path
  end
end

.memoize(key_prefix, expiry = nil) ⇒ Object

Memoize a method with a thread-safe cache

Parameters:

  • key_prefix (String)

    the cache key prefix

  • expiry (Integer) (defaults to: nil)

    optional expiry in seconds

Returns:

  • (Object)

    the memoized result



182
183
184
185
186
187
188
189
190
191
# File 'lib/ukiryu/utils.rb', line 182

def memoize(key_prefix, expiry = nil)
  cache = @memo_cache ||= {}
  cache_key = expiry ? "#{key_prefix}:#{Time.now.to_i / expiry}" : key_prefix

  return cache[cache_key] if cache.key?(cache_key)

  result = yield
  cache[cache_key] = result
  result
end

.safe_require(path) ⇒ Boolean

Safely require a file, caching the result

Parameters:

  • path (String)

    the file path to require

Returns:

  • (Boolean)

    true if loaded, false if already loaded



68
69
70
71
72
73
74
75
76
# File 'lib/ukiryu/utils.rb', line 68

def safe_require(path)
  require path
  true
rescue LoadError => e
  raise e
rescue RuntimeError
  # Already loaded
  false
end

.shell_escape(str, shell = :unix) ⇒ String

Escape a string for shell usage

Parameters:

  • str (String)

    the string to escape

  • shell (Symbol) (defaults to: :unix)

    the shell type (:unix, :windows, :powershell)

Returns:

  • (String)

    escaped string



115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ukiryu/utils.rb', line 115

def shell_escape(str, shell = :unix)
  case shell
  when :unix
    str.to_s.inspect
  when :powershell
    "'#{str.to_s.gsub("'", "''")}'"
  when :windows
    str.to_s.gsub('"', '^^"')
  else
    str.to_s
  end
end

.symbolize_keys(hash) ⇒ Hash

Recursively symbolize hash keys

Converts all string keys to symbols, including nested hashes and arrays containing hashes.

Examples:

Utils.symbolize_keys({ 'foo' => 'bar', 'nested' => { 'key' => 'value' } })
# => { foo: 'bar', nested: { key: 'value' } }

Parameters:

  • hash (Hash)

    the hash to symbolize

Returns:

  • (Hash)

    hash with symbolized keys



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/ukiryu/utils.rb', line 31

def symbolize_keys(hash)
  hash.transform_keys { |k| k.to_s.to_sym }.transform_values do |value|
    case value
    when Hash
      symbolize_keys(value)
    when Array
      value.map { |v| v.is_a?(Hash) ? symbolize_keys(v) : v }
    else
      value
    end
  end
end