SkillAgentSearch skills...

Matchete

A DSL for method overloading in Ruby based on pattern matching

Install / Use

/learn @alehander92/Matchete
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Matchete

Matchete provides a DSL for method overloading based on pattern matching for Ruby.

Build Status

It's just a quick hack inspired by weissbier and the use-return-values-of-method-definitions DSL technique used in harmonic

It supports only ruby 2.1+

Features

  • on [:value, Integer] matches an arg with the same internal structure
  • on '#method_name' matches args responding to method_name
  • on AClass matches instances of AClass
  • on a: 2, method:... matches keyword args
  • on :test? matches with user-defined predicate methods
  • on either('#count', Array) matches if any of the tests returns true for an arg
  • on full_match('#count', '#combine') matches if all of the tests return true for an arg
  • on exact(Integer) matches special values, used as shortcuts in other cases: classes, strings starting with '#', etc
  • on having('#count' => 2) matches objects with properties with certain values
  • default matches when no match has been found in on branches

Install

gem install matchete

Usage

class Translator
  include Matchete

  on Any, :string,
  def translate(value, to)
    value.to_s
  end

  on '#-@', :negative,
  def translate(value, to)
    - value
  end

  on String, :integer,
  def translate(value, to)
    value.to_i
  end

  default def translate(value, to)
    0
  end
end

t = Translator.new
p t.translate 72, :negative # -72
p t.translate nil, :integer # 0
require 'matchete'

class FactorialStrikesAgain
  include Matchete

  on 1,
  def factorial(value)
    1
  end

  on -> x { x > 1 },
  def factorial(value)
    value * factorial(value - 1)
  end
end

FactorialStrikesAgain.new.factorial(4) #24
FactorialStrikesAgain.new.factorial(-2) #Matchete::NotResolvedError No matching factorial method for args [-2]
class Converter
  include Matchete

  on '#special_convert',
  def convert(value)
    value.special_convert
  end

  on Integer,
  def convert(value)
    [:integer, value]
  end

  on Hash,
  def convert(values)
    [:dict, values.map { |k, v| [convert(k), convert(v)] }]
  end

  on /reserved_/,
  def convert(value)
    [:reserved_symbol, value]
  end

  on String,
  def convert(value)
    [:string, value]
  end

  on ['deleted', [Integer, Any]],
  def convert(value)
    ['deleted', value[1]]
  end

  on :starts_with_cat?,
  def convert(value)
    [:fail, value]
  end

  on free: Integer, method:
  def convert(free:)
    [:rofl, free]
  end

  on either('#count', Array),
  def convert(value)
    value.count
  end

  on full_match('#count', '#lala'),
  def convert(value)
    value.count + value.lala
  end

  default def convert(value)
    [:z, value]
  end

  def starts_with_cat?(value)
    value.to_s.start_with?('cat')
  end
end

class Z
  def special_convert
    [:special_convert, nil]
  end
end

converter = Converter.new
p Converter.instance_methods
p converter.convert(2) #[:integer, 2]
p converter.convert(Z.new) #[:special_convert, nil]
p converter.convert([4, 4]) # 2
p converter.convert({2 => 4}) #[:dict, [[[:integer, 2], [:integer, 4]]]
p converter.convert('reserved_l') #[:reserved_symbol, 'reserved_l']
p converter.convert('zaza') #[:string, 'zaza']
p converter.convert(['deleted', [2, Array]]) #['deleted', [2, Array]]
p converter.convert(:cat_hehe) #[:fail, :cat_hehe]
p converter.convert(free: 2) #[:rofl, 2]
p converter.convert(2.2) #[:z, 2.2]

version

0.5.1

cbb

Todo

  • Clean up the specs, right now they're a mess.
  • Fix all kinds of edge cases

Copyright

Copyright (c) 2015 Alexander Ivanov. See LICENSE for further details.

Related Skills

View on GitHub
GitHub Stars55
CategoryDevelopment
Updated2y ago
Forks3

Languages

Ruby

Security Score

85/100

Audited on Jul 11, 2023

No findings