Uma das coisas legais sobre o ruby é que você pode chamar métodos e executar código em locais que outras linguagens desaprovariam, como nas definições de método ou classe.
Por exemplo, para criar uma classe que tenha uma superclasse desconhecida até o tempo de execução, ou seja, seja aleatória, você pode fazer o seguinte:
class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample
end
RandomSubclass.superclass # could output one of 6 different classes.
Isso usa o Array#sample
método 1.9 (somente na versão 1.8.7, veja Array#choice
), e o exemplo é bastante artificial, mas você pode ver o poder aqui.
Outro exemplo interessante é a capacidade de colocar valores de parâmetro padrão que não são fixos (como outros idiomas costumam exigir):
def do_something_at(something, at = Time.now)
# ...
end
Obviamente, o problema com o primeiro exemplo é que ele é avaliado no momento da definição, não no tempo de chamada. Assim, uma vez escolhida uma superclasse, ela permanece nessa superclasse pelo restante do programa.
No entanto, no segundo exemplo, toda vez que você chamar do_something_at
, a at
variável será a hora em que o método foi chamado (bem, muito, muito próximo a ele)