Quick actions

cmd+k|ctrl+k

Navigation

Languages

fake pattern match (`case in` in ruby 2.7)

Snippet info

Language

Ruby

Visibility

public

Author

hyrious

Created

2019-04-19T02:22:55Z

Updated

2019-04-19T02:26:38Z

class M
  class << self
    def m *pat
      pat.empty? ? @m || [] : @m = (new *pat)
    end
    alias [] m
    def call b
      @m || (@m.call b)
    end
  end
  def initialize *pat
    @pat = pat
  end
  def === rhs
    @obj = rhs
    to_a.all? { |k| rhs.respond_to? k } # can we go deeper?
  end
  def to_a
    if Hash === @pat[-1]
      *a, b = @pat
      [*a, *b.keys]
    else
      @pat
    end
  end
  def to_h
    ret = {}
    if Hash === @pat[-1]
      @pat[-1].each { |k, v| ret[v] = @obj.send k }
    end
    ret
  end
#   def call b
#     to_h.each { |k, v| b.local_variable_set k, v }
#     self
#   end
  def call s
    to_h.each { |k, v|
      s.singleton_class.class_eval { attr_accessor k }
      s.send :"#{k}=", v
    }
    self
  end
end

def m(*a)
  M[*a]
end

A = Struct.new :a
case A.new 42
when m(a: 'b')
  m.(self)
  p b
end
INFO