B Seven
B Seven

Reputation: 45943

How to use alias with parameters in Ruby?

I would like to refactor this code:

  class Logger
    class << self
      def info title, msg
        puts hash_for(title, msg, :info ).to_json
      end

      def unknown title, msg
        puts hash_for(title, msg, :unknown).to_json
      end

Into something like:

def print title, msg, level
  puts hash_for(title, msg, level).to_json
end
alias :info, :print
alias :unknown, :print

But I need to inject the argument, which alias and alias_method do not appear to support.

Ruby 2.3

Upvotes: 0

Views: 1393

Answers (3)

Ehren Murdick
Ehren Murdick

Reputation: 436

You can do this with meta programming!

class Logger
  def self.define_printer(level)
    define_singleton_method(level) do |title, msg|
      print(title, msg, level)
    end
  end

  def self.print(title, msg, level)
    puts hash_for(title, msg, level).to_json
  end

  define_printer :info
  define_printer :unknown
end

Logger.info('foo', 'bar')
# calls print with ["foo", "bar", :info]

Edit: For extra credit, I made a more general version.

class Object
  def curry_singleton(new_name, old_name, *curried_args)
    define_singleton_method(new_name) do |*moreArgs|
      send(old_name, *curried_args.concat(moreArgs))
    end
  end
end

class Foobar
  def self.two_arg_method(arg1, arg2)
    p [arg1, arg2]
  end

  curry_singleton(:one_arg_method, :two_arg_method, 'first argument')
end
Foobar.one_arg_method('second argument')
#=> ["first argument", "second argument"]

Upvotes: 2

Marc Rohloff
Marc Rohloff

Reputation: 1352

alias is a built in and won't support a parameter, in fact alias info print without colons or commas is syntactically correct. But alias_method should work. The following worked for me:

class G

  def print
    puts 'print'
  end

  a = :print
  b = :info
  alias_method b, a

end

G.new.info

Upvotes: 0

Ryenski
Ryenski

Reputation: 9692

As far as I know neither alias nor alias_method support arguments.

You could define the methods explicitly like this:

def print(title, msg, level)
  puts hash_for(title, msg, level).to_json
end

def info(*args)
  print(*args)
end

# More concise...
def unknown(*args); print(*args); end

Upvotes: 0

Related Questions