Uma das coisas muito legais que o Java possui é sobrecarga de métodos (várias vezes confundido com polimorfismo) que é a capacidade de possuir métodos diferentes com mesmo nome, mas com parâmetros diferentes.
Bom, isso não existe em Ruby, mas nada impede que isso seja implementado. Rascunhei isso aqui:
class Object
def self.generate_method_name_for(method_name, *parameter_types)
# Usamos espaços no nome dos métodos gerados para evitar chamadas acidentais
"#{method_name}_#{parameter_types.collect{|it| it.to_s}.join(' ')}".to_sym
end
def self.def_method(method_name, *parameter_types, &block)
# Definindo o método genérico da classe,
define_method method_name.to_sym do |*params|
send("#{method_name}_#{params.collect{|it| it.class.to_s}.join(' ')}", *params)
end unless self.method_defined?(method_name.to_sym)
#Definindo cada método específico
specific_method = generate_method_name_for(method_name, *parameter_types)
define_method(specific_method, &block)
end
end
E para usar:
class Test
def_method :test, String, String do |a, b|
puts "Duas strings"
end
def_method :test, String do |a|
puts "Uma string"
end
def_method :test, Fixnum do |a|
puts "Um número"
end
end
x = Test.new
x.test("a", "b")
x.test("a")
x.test(1)
É lógico que isso custa desempenho, mas serve. Acho também que o código poderia ser grandemente melhorado, até pq não sei se isso funcionaria corretamente com herança e polimorfismo, mas não quis perder mais tempo brincando nisso :)
Moral da história: adoro classes abertas.
Caramba, esse foi o maior estupro do Ruby que eu vi até agora. :-) Existe alguma justificativa para precisar disso?
ResponderExcluirTambém acho! Não seria mais fácil receber um hash, por exemplo?
ResponderExcluirNão seria mais simples:
ResponderExcluirclass Test
def test(a,b=nil)
b ? puts "Duas strings" : puts "Uma string"
end
end
x = Test.new
x.test("a", "b")
x.test("a")
Ou, caso a lista de parâmetros seja muito grande, fico com o Nando, receber um hash! E o melhor disso: os parâmetros não precisam ser passados em uma ordem certa! :)
Huahuahuahua,
ResponderExcluirNão, não existe justificativa pra usar um código desses. Foi só pra pq um dia eu estava pensando "puxa, sobrecarga de métodos é legal, pena que Ruby não tem". Aí pensei se não seria possível fazer, já que Ruby é bem extensível. Bom... é possível :)
Aí depois de fazer isso eu olhei e pensei comigo mesmo "Nahhh... nem vale a pena" :) Mas fica como um exercício e prova de que você mesmo pode fazer muita coisa em Ruby.
Mas como toda faca afiada, se não usar com cuidado, corta o dedo ;)
@arthurgeek
ResponderExcluirAté seria possível, mas não teria como fazer sobrecarga com um Inteiro ao invés de String :)
Ronie, tá sobrando tempo aí! hahhahahah
ResponderExcluir"Uma das coisas muito legais que o Java possui é sobrecarga de métodos (várias vezes confundido com polimorfismo) que é a capacidade de possuir métodos diferentes com mesmo nome, mas com parâmetros diferentes."
ResponderExcluirNa realidade e segunda a literatura, sobrecarga é um tipo de polimorfismo ("várias formas").
Pode-se definir polimorfismo como sendo a capacidade de um operador executar o comportamento adequado de acordo com o operando, onde operador/ operando pode ser: método/classe, método/parametros(sobrecarga), etc.
Só pra complementar o comentário acima, isso é conhecido como Polimorfismo Ad-Hoc por sobrecarga.
ResponderExcluir