2017-02-23 24 views
0

我想重構這個代碼:如何在Ruby中使用帶有參數的別名?

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似乎並不支持。

紅寶石2.3

回答

0

據我所知沒有alias也不alias_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 
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 
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"] 
+0

是的,這似乎是一個好方法... –

相關問題