Continuando o meme "Recursos ocultos de ...", vamos compartilhar os recursos menos conhecidos, mas úteis, da linguagem de programação Ruby.
Tente limitar essa discussão com o Ruby principal, sem nenhum material do Ruby on Rails.
Veja também:
- Recursos ocultos do C #
- Recursos ocultos do Java
- Recursos ocultos do JavaScript
- Recursos ocultos do Ruby on Rails
- Recursos ocultos do Python
(Por favor, apenas um recurso oculto por resposta.)
Obrigado
ruby
hidden-features
esquadrão
fonte
fonte
Respostas:
No Ruby 1.9, Proc # === é um apelido para a chamada Proc #, o que significa que os objetos Proc podem ser usados em instruções de caso como:
fonte
Peter Cooper tem uma boa lista de truques de Ruby. Talvez o meu favorito dele seja permitir que itens e coleções individuais sejam enumerados. (Ou seja, trate um objeto que não é de coleção como uma coleção que contém apenas esse objeto.) Parece com isso:
fonte
items
é uma string, você não precisa anexá-la com [*…]. String.each não repete os caracteres, como alguns podem esperar. Apenas retorna ao bloco.Não sei o quanto isso está oculto, mas achei útil ao precisar criar um Hash a partir de uma matriz unidimensional:
fonte
Hash[ [["apple","red"], ["banana","yellow"] ]
produz o mesmo resultado.Um truque que eu gosto é usar o
*
expansor splat ( ) em objetos que não sejam Arrays. Aqui está um exemplo de uma correspondência de expressão regular:Outros exemplos incluem:
fonte
text, number = *"text 555".match(/regexp/)[1..-1]
.text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
Uau, ninguém mencionou o operador flip-flop:
fonte
i == 3
e muda para falso depois dei != 3
ei == 15
. Semelhante a um flip-flop: en.wikipedia.org/wiki/Flip-flop_%28electronics%29Uma 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:
Isso usa o
Array#sample
método 1.9 (somente na versão 1.8.7, vejaArray#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):
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
, aat
variável será a hora em que o método foi chamado (bem, muito, muito próximo a ele)fonte
require 'activesupport'
Outro pequeno recurso - converta um
Fixnum
em qualquer base até 36:E, como Huw Walters comentou, converter para o outro lado é igualmente simples:
fonte
String#to_s(base)
pode ser usado para converter de volta para um número inteiro;"1001001100101100000001011010010".to_i(2)
,"499602d2".to_i(16)
etc , todos retornam o originalFixnum
.Hashes com valores padrão! Uma matriz neste caso.
Muito útil em metaprogramação.
fonte
Faça o download da fonte e do problema do Ruby 1.9, e
make golf
você poderá fazer coisas como estas:Leia o artigo
golf_prelude.c
para coisas mais legais escondidas.fonte
Outra adição divertida na funcionalidade 1.9 Proc é o Proc # curry, que permite transformar um Proc que aceita n argumentos em um que aceita n-1. Aqui, ele é combinado com a dica Proc # === que mencionei acima:
fonte
Operadores booleanos em valores não booleanos.
&&
e||
Ambos retornam o valor da última expressão avaliada.
É por isso
||=
que atualizará a variável com o valor retornado pela expressão no lado direito, se a variável for indefinida. Isso não está explicitamente documentado, mas o conhecimento comum.No entanto, o
&&=
assunto não é tão amplamente conhecido.é equivalente a
É muito útil para operações destrutivas que não devem prosseguir se a variável não estiver definida.
fonte
string &&= string + "suffix"
é equivalente astring = string && string + "suffix"
. Isso&&
e||
retornar seu segundo argumento é discutido no PickAx, p. 154 (Parte I - Facetas de Ruby, Expressões, Execução Condicional).A função Symbol # to_proc fornecida pelo Rails é muito legal.
Ao invés de
Você pode escrever:
fonte
require 'activesupport'
pois é daí que a maioria desses ajudantes é.Uma final - em ruby, você pode usar qualquer caractere que queira delimitar strings. Pegue o seguinte código:
Se você não quiser escapar das aspas duplas na cadeia, basta usar um delimitador diferente:
Além de evitar a necessidade de escapar dos delimitadores, você pode usá-los para obter seqüências multilinhas mais agradáveis:
fonte
Acho que o uso do comando define_method para gerar dinamicamente métodos é bastante interessante e pouco conhecido. Por exemplo:
O código acima usa o comando 'define_method' para criar dinamicamente os métodos "press1" a "press9". Em vez de digitar todos os 10 métodos que contêm essencialmente o mesmo código, o comando define method é usado para gerar esses métodos rapidamente, conforme necessário.
fonte
Use um objeto Range como uma lista lenta infinita:
Mais informações aqui: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/
fonte
module_function
Os métodos do módulo declarados como module_function criarão cópias de si mesmos como métodos de instância privada na classe que inclui o Módulo:
Se você usar module_function sem argumentos, quaisquer métodos de módulo que venham após a instrução module_function se tornarão automaticamente module_functions.
fonte
module_function
(2º modo) é usar apenasextend self
(que parece muito bom: D)Injeção curta, assim:
Soma do intervalo:
fonte
require 'backports'
:-)Atenção: este item foi votado como o número 1 do jogo mais horrendo de 2008 , então use com cuidado. Na verdade, evite-o como uma praga, mas certamente é Ruby Oculto.
Operadores adicionam novos operadores ao Ruby
Você já desejou um operador de handshake super secreto para alguma operação exclusiva em seu código? Como jogar código de golfe? Tente operadores como - ~ + ~ - ou <--- Esse último é usado nos exemplos para reverter a ordem de um item.
Não tenho nada a ver com o Projeto Superators além de admirá-lo.
fonte
Estou atrasado para a festa, mas:
Você pode facilmente pegar duas matrizes de tamanho igual e transformá-las em um hash, com uma matriz fornecendo as chaves e a outra os valores:
(Isso funciona porque a matriz # zip "fecha os valores das duas matrizes:
E o Hash [] pode receber exatamente essa matriz. Vi pessoas fazerem isso também:
O que produz o mesmo resultado, mas o splat e o achatamento são totalmente desnecessários - talvez não existissem no passado?)
fonte
Hash vivificantes automáticos em Ruby
Isso pode ser muito útil.
fonte
module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
Reestruturando uma matriz
Onde:
Usando essa técnica, podemos usar uma atribuição simples para obter os valores exatos que queremos da matriz aninhada de qualquer profundidade.
fonte
Class.new()
Crie uma nova classe em tempo de execução. O argumento pode ser uma classe para derivar, e o bloco é o corpo da classe. Você também pode querer
const_set/const_get/const_defined?
registrar sua nova turma corretamente, para queinspect
imprima um nome em vez de um número.Não é algo que você precisa todos os dias, mas bastante útil quando precisa.
fonte
MyClass = Class.new Array do; def hi; 'hi'; end; end
parece ser equivalente aclass MyClass < Array; def hi; 'hi'; end; end
.crie uma matriz de números consecutivos:
define x para [0, 1, 2, 3, 4, 5]
fonte
*
operador splat ( ) basicamente chamato_a
assim mesmo.Muita mágica que você vê em Rubyland tem a ver com metaprogramação, que é simplesmente escrever código que escreve código para você. Ruby
attr_accessor
,attr_reader
eattr_writer
são todos simples metaprogramming, em que eles criam dois métodos em uma linha, seguindo um padrão normal. O Rails faz muita metaprogramação com seus métodos de gerenciamento de relacionamentos comohas_one
ebelongs_to
.Mas é bastante simples criar seus próprios truques de metaprogramação
class_eval
para executar código gravado dinamicamente.O exemplo a seguir permite que um objeto wrapper encaminhe certos métodos para um objeto interno:
O método
Wrapper.forwards
utiliza símbolos para os nomes dos métodos e os armazena namethods
matriz. Então, para cada um dos dados, usamosdefine_method
para criar um novo método cujo trabalho é enviar a mensagem, incluindo todos os argumentos e blocos.Um ótimo recurso para questões de metaprogramação é o porquê de "Seeing Metaprogramming Clearly", de Lucky Stiff .
fonte
use qualquer coisa que responda
===(obj)
para comparações de casos:Module
(e, assim,Class
),Regexp
,Date
, e muitas outras classes de definir um método de exemplo: === (outro), e podem todos ser usados.Agradecemos a Farrel pelo lembrete de
Proc#call
ser um alias, comoProc#===
no Ruby 1.9.fonte
O binário "ruby" (pelo menos ressonância magnética) suporta muitos dos switches que tornaram perl one-liners bastante populares.
Significativos:
put
s automático no final de cada iteração de loopAlguns exemplos:
Sinta-se à vontade para pesquisar no Google "one-liners ruby" e "perl one-liners" para obter exemplos mais úteis e práticos. Essencialmente, permite que você use o ruby como um substituto bastante poderoso para o awk e sed.
fonte
O método send () é um método de uso geral que pode ser usado em qualquer Classe ou Objeto no Ruby. Se não for substituído, send () aceita uma string e chama o nome do método cuja string é passada. Por exemplo, se o usuário clicar no botão “Clr”, a string 'press_clear' será enviada para o método send () e o método 'press_clear' será chamado. O método send () permite uma maneira divertida e dinâmica de chamar funções no Ruby.
Eu falo mais sobre esse recurso no Blogging Shoes: o aplicativo Simple-Calc
fonte
Engane alguma classe ou módulo dizendo que exigiu algo que realmente não era necessário:
Isso é útil, por exemplo, ao exigir A que, por sua vez, requer B, mas não precisamos de B em nosso código (e A não o utilizará também através de nosso código):
Por exemplo, Backgroundrb's
bdrb_test_helper requires
'test/spec'
, mas você não usa nada, portanto, no seu código:fonte
Fixnum#to_s(base)
pode ser realmente útil em alguns casos. Um desses casos é gerar tokens únicos aleatórios (pseudo), convertendo número aleatório em string usando a base de 36.Token de comprimento 8:
Token de comprimento 6:
fonte
Definindo um método que aceita qualquer número de parâmetros e apenas descarta todos eles
O
hello
método acima só precisaputs
"hello"
aparecer na tela e chamarsuper
- mas como a superclassehello
define os parâmetros, também é necessário - no entanto, como na verdade não precisa usar os parâmetros em si - não precisa dar um nome a eles.fonte