Skip to content

tejanium/loverload

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Loverload

DSL for building method overloading in Ruby.

Rigid language like Java allow you to create method overloading:

public void draw(String s) {
    ...
}
public void draw(int i) {
    ...
}
public void draw(double f) {
    ...
}
public void draw(int i, double f) {
    ...
}

However, in Ruby, we don't have this kind of thing, do we?

before_save NameSayer.new
before_save :say_my_name
before_save {|record| puts "My name is #{record.name}" }
before_save 'puts "My name is #{self.name}"'

An Intervention for ActiveRecord by Ernie Miller

Installation

Add this line to your application's Gemfile:

gem 'loverload'

And then execute:

$ bundle

Or install it yourself as:

$ gem install loverload

Usage

Simple

class Dummy
  include Loverload

  def_overload :hello do
    with_params do
      "Hello Nobody"
    end

    with_params do |name|
      "Hello #{ name }"
    end

    with_params do |name, age|
      "Hello #{ name } Age #{ age }"
    end
  end
end

dummy = Dummy.new
dummy.hello #=> 'Hello Nobody'
dummy.hello('Teja') #=> 'Hello Teja'
dummy.hello('Teja', 21) #=> 'Hello Teja Age 21'

Strict

class Dummy
  include Loverload

  def_overload :hello do
    with_params String do |name|
      "Hello Name: #{ name }"
    end

    with_params Fixnum do |age|
      "Hello Age: #{ age }"
    end

    with_params String, Fixnum do |name, age|
      "Hello Name: #{ name } Age: #{ age }"
    end

    with_params Fixnum, String do |age, name|
      "Hello Age: #{ age } Name: #{ name }"
    end
  end
end

dummy = Dummy.new
dummy.hello('Teja') #=> 'Hello Name: Teja'
dummy.hello(21) #=> 'Hello Age: 21'
dummy.hello('Teja', 21) #=> 'Hello Name: Teja Age: 21'
dummy.hello(21, 'Teja') #=> 'Hello Age: 21 Name: Teja'
dummy.hello('Teja', 21, true) #=> NoMethodError

This is how you do :before_save

class Dummy
  include Loverload

  def_overload :before_save do
    with_params Dummy do |dummy|
      "Puke rainbow"
    end

    with_params Symbol do |symbol|
      "Puke more rainbow"
    end

    with_params Proc do |proc|
      "Puke rainbow and leprechaun"
    end

    with_params String do |string|
      "Puke rainbow, leprechaun, and gold"
    end
  end
end

dummy = Dummy.new
dummy.before_save(Dummy.new) #=> "Puke rainbow"
dummy.before_save(:symbol) #=> "Puke more rainbow"
dummy.before_save(proc{|this| is proc}) #=> "Puke rainbow and leprechaun"
dummy.before_save('string') #=> "Puke rainbow, leprechaun, and gold"

It also support functor 'guard' arguments

class Dummy
  include Loverload

  def_overload :hello do
    with_params ->(num){ num.odd? } do |num|
      "Odd"
    end

    with_params ->(num){ num.even? } do |num|
      "Even"
    end
  end
end

dummy = Dummy.new
dummy.hello(1) #=> 'Odd'
dummy.hello(2) #=> 'Even'
dummy.hello(100) #> 'Even'

It also support functor fibonnaci with recursive method, but kinda reversed on method definition.

class Dummy
  include Loverload

  def_overload :fibonnaci do
    with_params 1 do |n|
      1
    end

    with_params 0 do |n|
      0
    end

    with_params Integer do |n|
      fibonnaci(n - 1) + fibonnaci(n - 2)
    end
  end
end

dummy = Dummy.new

[*0..10].map(&dummy.method(:fibonnaci)) #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

TODO

  • Cache?

NOTES

Couple weeks ago, while searching for the same library, I found yanked gem called overload from 2009, it's such an coincidence that we used similar implementation, inside it's readme, the author mentioned functor, similar gem with different approach. Then I decided to change loverload implementation using functor approach, an simple but expensive approach.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

About

DSL for building method overloading in Ruby.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages