如何在Ruby中使用带参数的别名?

时间:2017-02-23 17:56:53

标签: ruby alias ruby-2.3

我想重构这段代码:

  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

类似于:

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

但我需要注入aliasalias_method似乎不支持的参数。

Ruby 2.3

3 个答案:

答案 0 :(得分:1)

你可以用元编程来做到这一点!

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]

编辑:为了额外的功劳,我制作了一个更通用的版本。

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"]

答案 1 :(得分:0)

据我所知,aliasalias_method都不支持论点。

您可以像这样明确定义方法:

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

答案 2 :(得分:0)

alias是内置的,不支持参数,实际上alias info print没有冒号或逗号在语法上是正确的。但alias_method应该有用。以下对我有用:

class G

  def print
    puts 'print'
  end

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

end

G.new.info