module Obfusk

Constants

ADT_Meta__
DATE
VERSION

Public Class Methods

List(*xs, &b) click to toggle source

create a list from its items; pass a block to add a lazy tail

# File lib/obfusk/list.rb, line 250
def self.List(*xs, &b)
  b && xs.length == 1 ? Cons(xs.first, &b)  :
  b && xs.empty?      ? b._                 :
  xs.empty?           ? Nil()               :
  Cons(xs.first) { List(*xs.drop(1), &b) }
end
atom(value) click to toggle source

create an Atom

# File lib/obfusk/atom.rb, line 39
def self.atom(value)
  Atom.new value
end
eager(x) click to toggle source

eager: evaluate if lazy, just return if not

# File lib/obfusk/lazy.rb, line 35
def self.eager(x)
  lazy?(x) ? x._ : x
end
get_in(o, *ks, &b) click to toggle source

get nested key in nested datastructure

# File lib/obfusk/data.rb, line 42
def self.get_in(o, *ks, &b)
  ks.each { |k| o = o.fetch(k) { return b ? b[] : nil } }; o
end
lazy(x = nil, &b) click to toggle source

lazy evaluation (thunk)

# File lib/obfusk/lazy.rb, line 16
def self.lazy(x = nil, &b)
  return x if lazy? x
  f = b ? b : -> { x }; v = nil; e = false
  g = -> () { unless e then v = f[]; e = true end; v }
  g.define_singleton_method(:__obfusk_lazy__?) { true }
  g.define_singleton_method(:_)     { g[] }
  g.define_singleton_method(:deref) { g[] }
  g.define_singleton_method(:chain) do |m,*a,&b|
    ::Obfusk::lazy { g[].public_send(m,*a,&b) }
  end
  g
end
lazy?(x) click to toggle source

lazy?

# File lib/obfusk/lazy.rb, line 30
def self.lazy?(x)
  x.respond_to?(:__obfusk_lazy__?) && x.__obfusk_lazy__?
end
merge(x, h = {}) click to toggle source

merge anything that responds to ‘.obfusk_merge` or `.merge`

# File lib/obfusk/data.rb, line 30
def self.merge(x, h = {})
  x.respond_to?(:__obfusk_merge__) ? x.__obfusk_merge__(h) : x.merge(h)
end
merge!(x, h = {}) click to toggle source

merge anything that responds to ‘.obfusk_merge!` or `.merge!`

# File lib/obfusk/data.rb, line 35
def self.merge!(x, h = {})
  x.respond_to?(:__obfusk_merge__!) ? x.__obfusk_merge__!(h) : x.merge!(h)
end
modify_in(o, k, *ks, &b) click to toggle source

swap value for nested key in nested datastructure; autovivifies missing keys as hashes @return a new datastructure

# File lib/obfusk/data.rb, line 49
def self.modify_in(o, k, *ks, &b)
  ks_ = [k] + ks; os = nested_objects o, *ks_; o_ = b[os.pop]
  ks_.reverse.each { |k| o_ = merge(os.pop, k => o_) }; o_
end
modify_in!(o, k, *ks, &b) click to toggle source

swap value for nested key in nested datastructure; autovivifies missing keys as hashes @return modified datastructure

# File lib/obfusk/data.rb, line 57
def self.modify_in!(o, k, *ks, &b)
  ks_ = [k] + ks; os = nested_objects o, *ks_; o_ = b[os.pop]
  ks_.reverse.each { |k| o_ = merge!(os.pop, k => o_) }; o_
end
nested_objects(o, *ks) click to toggle source

get stack of objects for nested key in nested datastructure; autovivifies missing keys as hashes

# File lib/obfusk/data.rb, line 64
def self.nested_objects(o, *ks)
  [o] + ks.map { |k| o = o.fetch(k) { {} } }
end
set_in(o, *ks, v) click to toggle source

set value for nested key in nested datastructure @return a new datastructure

# File lib/obfusk/data.rb, line 70
def self.set_in(o, *ks, v)
  modify_in(o, *ks) { |_| v }
end
set_in!(o, *ks, v) click to toggle source

set value for nested key in nested datastructure @return modified datastructure

# File lib/obfusk/data.rb, line 76
def self.set_in!(o, *ks, v)
  modify_in!(o, *ks) { |_| v }
end