Recursos ocultos do Ruby

160

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:

(Por favor, apenas um recurso oculto por resposta.)

Obrigado

esquadrão
fonte
deve ser wiki da comunidade
SilentGhost

Respostas:

80

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:

def multiple_of(factor)
  Proc.new{|product| product.modulo(factor).zero?}
end

case number
  when multiple_of(3)
    puts "Multiple of 3"
  when multiple_of(7)
    puts "Multiple of 7"
end
Farrel
fonte
1
Na verdade, eu escrevi uma jóia em um ponto para fazer isso, mas meu código era (a) uma bagunça e (b) lento. Estou muito feliz que a funcionalidade tenha se tornado essencial.
James A. Rosen
76

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:

[*items].each do |item|
  # ...
end
James A. Rosen
fonte
38
Uma forma mais explícita (e, portanto, mais agradável) disso é Array (items)
.each
Se 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.
Mxcl
Para que serve isso? Apenas curioso.
Ed S.
1
@ Ed: é bom se você estiver escrevendo um método e quiser permitir que o usuário do método passe uma lista de varargs ou uma matriz.
James A. Rosen
64

Não sei o quanto isso está oculto, mas achei útil ao precisar criar um Hash a partir de uma matriz unidimensional:

fruit = ["apple","red","banana","yellow"]
=> ["apple", "red", "banana", "yellow"]

Hash[*fruit]    
=> {"apple"=>"red", "banana"=>"yellow"}
astronautismo
fonte
Observe que Hash[ [["apple","red"], ["banana","yellow"] ]produz o mesmo resultado.
Marc-André Lafortune
54

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:

match, text, number = *"Something 981".match(/([A-z]*) ([0-9]*)/)

Outros exemplos incluem:

a, b, c = *('A'..'Z')

Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom
tomafro
fonte
13
Aliás, para os curiosos, isso funciona implicitamente chamando to_a no destino do splat.
22610 Bob Aman
1
Se você não está interessado na partida, você pode ter text, number = *"text 555".match(/regexp/)[1..-1].
Andrew Grimm
text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
Jonas Elfström
7
Ambos os bons truques, mas tem que haver um ponto em que é muita mágica, certo ?!
tomafro 22/01
1
@ Andrew, você considerou que esse jogo pode retornar nulo? nil não tem método [] #
Alexey
52

Uau, ninguém mencionou o operador flip-flop:

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end
Konstantin Haase
fonte
11
Certo ... alguém vai ter que me explicar essa. Funciona, mas não consigo entender o porquê.
Bob Aman
12
O operador flip-flop é um estado completo se. Seu estado muda para verdadeiro assim que i == 3e muda para falso depois de i != 3 e i == 15. Semelhante a um flip-flop: en.wikipedia.org/wiki/Flip-flop_%28electronics%29
Konstantin Haase
1
Eu não chamaria exatamente isso de um recurso oculto, tanto de um aborrecimento. Lembro-me da primeira vez em que fui apresentado a ele no #Ruby on Freenode, anos atrás; Eu usei basicamente todos os recursos do Ruby em algum momento, exceto este.
ELLIOTTCABLE
1
Eu não chamaria isso de aborrecimento, é apenas algo que você não usou. Eu o uso e ele pode reduzir muito bem o código, especialmente quando estou obtendo blocos de linhas de arquivos com base em alguns critérios.
the Tin Man
49

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#samplemé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 atvariável será a hora em que o método foi chamado (bem, muito, muito próximo a ele)

bjeanes
fonte
2
Nota: Array # rand é fornecido pelo ActiveSupport que você pode usar fora do Rails tão facilmente comorequire 'activesupport'
rfunduk
A escolha da matriz # está em 1.8.7
Josh Lee
24
A escolha da matriz # é somente 1.8.7 ! Não o use, ele foi lançado em 1.9 e será lançado em 1.8.8. Use #sample
Marc-André Lafortune
python: classe DictList ([dict, list] [random.randint (0,1)]): pass
Anurag Uniyal
def do_something_at (alguma coisa, em = lambda {Time.now}) at.call #now atribuir dinamicamente o tempo final
Jack Kinsella
47

Outro pequeno recurso - converta um Fixnumem qualquer base até 36:

>> 1234567890.to_s(2)
=> "1001001100101100000001011010010"

>> 1234567890.to_s(8)
=> "11145401322"

>> 1234567890.to_s(16)
=> "499602d2"

>> 1234567890.to_s(24)
=> "6b1230i"

>> 1234567890.to_s(36)
=> "kf12oi"

E, como Huw Walters comentou, converter para o outro lado é igualmente simples:

>> "kf12oi".to_i(36)
=> 1234567890
tomafro
fonte
1
E, para ser completo, 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 original Fixnum.
Huw Walters
40

Hashes com valores padrão! Uma matriz neste caso.

parties = Hash.new {|hash, key| hash[key] = [] }
parties["Summer party"]
# => []

parties["Summer party"] << "Joe"
parties["Other party"] << "Jane"

Muito útil em metaprogramação.

August Lilleaas
fonte
1
sim, verdade. O hash Ruby pode aceitar o operador '<<' se já houver um valor padrão atribuído com '=' (não importa, mesmo que seja uma atribuição vazia), caso contrário, o hash não aceitará '<<'. CMIIW
mhd
39

Faça o download da fonte e do problema do Ruby 1.9, e make golfvocê poderá fazer coisas como estas:

make golf

./goruby -e 'h'
# => Hello, world!

./goruby -e 'p St'
# => StandardError

./goruby -e 'p 1.tf'
# => 1.0

./goruby19 -e 'p Fil.exp(".")'
"/home/manveru/pkgbuilds/ruby-svn/src/trunk"

Leia o artigo golf_prelude.cpara coisas mais legais escondidas.

manveru
fonte
38

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:

it_is_day_of_week = lambda{ |day_of_week, date| date.wday == day_of_week }
it_is_saturday = it_is_day_of_week.curry[6]
it_is_sunday = it_is_day_of_week.curry[0]

case Time.now
when it_is_saturday
  puts "Saturday!"
when it_is_sunday
  puts "Sunday!"
else
  puts "Not the weekend"
end
Farrel
fonte
35

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.

string &&= string + "suffix"

é equivalente a

if string
  string = string + "suffix"
end

É muito útil para operações destrutivas que não devem prosseguir se a variável não estiver definida.

EmFi
fonte
2
Mais precisamente, string &&= string + "suffix" é equivalente a string = string && string + "suffix". Isso &&e ||retornar seu segundo argumento é discutido no PickAx, p. 154 (Parte I - Facetas de Ruby, Expressões, Execução Condicional).
Richard Michael
29

A função Symbol # to_proc fornecida pelo Rails é muito legal.

Ao invés de

Employee.collect { |emp| emp.name }

Você pode escrever:

Employee.collect(&:name)
hoyhoy
fonte
Aparentemente, essa é uma "ordem de magnitude mais lenta" do que usar um bloco. igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri
Charles Roper
Eu apenas tentei e descobri que não havia diferença significativa entre os dois. Não sei de onde veio esse material de "ordem de magnitude". (Usando o Ruby 1.8.7)
Matt Grande
1
Fazer isso fora do Rails também é útil e pode ser feito, require 'activesupport'pois é daí que a maioria desses ajudantes é.
rfunduk 22/06/09
8
isso costumava ser lento por causa da implementação do active_support, ou seja, ele aceitava vários argumentos para que você pudesse fazer coisas legais como (1..10) .inject &: *, mas o principal caso de uso costumava chamar apenas um método em cada membro de um coleção, por exemplo,% w (a raposa marrom rápida) .map &: upcase. a partir de 1.8.7, é o ruby ​​principal e o desempenho é razoável.
Steve Graham
4
@thenduks: E isso pode ser feito sem a ajuda do activeesupport no ruby ​​1.8.7 e 1.9.
Andrew Grimm
28

Uma final - em ruby, você pode usar qualquer caractere que queira delimitar strings. Pegue o seguinte código:

message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"

Se você não quiser escapar das aspas duplas na cadeia, basta usar um delimitador diferente:

contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]

Além de evitar a necessidade de escapar dos delimitadores, você pode usá-los para obter seqüências multilinhas mais agradáveis:

sql = %{
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
}
tomafro
fonte
19
Não qualquer personagem, mas ainda é muito legal. Também funciona com outros literais:% () /% {} /% [] /% <> /% || % r () /% r {} /% r [] /% r <> /% r || % w () /% w {} /% w [] /% w <> /% w ||
Bo Jeanes
Há também a sintaxe aqui e agora doc: << BLOCK ... bloco, que eu gosto de usar para coisas como instruções SQL de várias linhas etc.
Martin T.
26

Acho que o uso do comando define_method para gerar dinamicamente métodos é bastante interessante e pouco conhecido. Por exemplo:

((0..9).each do |n|
    define_method "press_#{n}" do
      @number = @number.to_i * 10 + n
    end
  end

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.

CodingWithoutComments
fonte
4
O único problema com o define_method é que ele não permite que os blocos sejam passados ​​como parâmetros no ruby ​​1.8. Consulte esta postagem do blog para obter uma solução alternativa.
Andrew Grimm
26

Use um objeto Range como uma lista lenta infinita:

Inf = 1.0 / 0

(1..Inf).take(5) #=> [1, 2, 3, 4, 5]

Mais informações aqui: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/

horseyguy
fonte
O lazy_select no artigo vinculado é muito elegante.
Joseph Weissman
Isso é realmente incrível. Eu gosto de como o Infinity é um float, dessa maneira, quando tentei isso: (-Inf..Inf) .take (4) levantou um (logicamente consistente) não pode iterar do erro de flutuação. : D
zachaysan
23

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:

module M
  def not!
    'not!'
  end
  module_function :not!
end

class C
  include M

  def fun
    not!
  end
end

M.not!     # => 'not!
C.new.fun  # => 'not!'
C.new.not! # => NoMethodError: private method `not!' called for #<C:0x1261a00>

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.

module M
  module_function

  def not!
    'not!'
  end

  def yea!
    'yea!'
  end
end


class C
  include M

  def fun
    not! + ' ' + yea!
  end
end
M.not!     # => 'not!'
M.yea!     # => 'yea!'
C.new.fun  # => 'not! yea!'
newtonapple
fonte
4
Se você apenas deseja declarar métodos privados em módulos, use a palavra-chave privada. Além de tornar o método privado em classes que incluem o módulo, module_function copia o método para a instância do módulo. Na maioria dos casos, não é isso que você deseja.
tomafro
Eu sei que você pode apenas usar privado. Mas essa é uma pergunta sobre os recursos ocultos do Ruby. E acho que a maioria das pessoas nunca ouviu falar de module_function (inclusive eu) até vê-lo no documento e começar a brincar com ele.
Newtonapple
Uma alternativa ao uso module_function(2º modo) é usar apenas extend self(que parece muito bom: D)
J -_- L
23

Injeção curta, assim:

Soma do intervalo:

(1..10).inject(:+)
=> 55
user130730
fonte
2
Vale a pena notar que você precisa do Ruby 1.9 ou Rails com Ruby 1.8 para que isso funcione.
Mxcl
1
@Max Howell: ou require 'backports':-)
Marc-André Lafortune
1
Isso não é uma duplicata da resposta de Hoyhoy?
Andrew Grimm
21

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.

Capitão Martelo
fonte
19

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:

a = [:x, :y, :z]
b = [123, 456, 789]

Hash[a.zip(b)]
# => { :x => 123, :y => 456, :z => 789 }

(Isso funciona porque a matriz # zip "fecha os valores das duas matrizes:

a.zip(b)  # => [[:x, 123], [:y, 456], [:z, 789]]

E o Hash [] pode receber exatamente essa matriz. Vi pessoas fazerem isso também:

Hash[*a.zip(b).flatten]  # unnecessary!

O que produz o mesmo resultado, mas o splat e o achatamento são totalmente desnecessários - talvez não existissem no passado?)

Jordan Running
fonte
3
De fato, isso não foi documentado por um longo tempo (consulte redmine.ruby-lang.org/issues/show/1385 ). Observe que este novo formulário é novo no Ruby 1.8.7
Marc-André Lafortune
19

Hash vivificantes automáticos em Ruby

def cnh # silly name "create nested hash"
  Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
my_hash = cnh
my_hash[1][2][3] = 4
my_hash # => { 1 => { 2 => { 3 =>4 } } }

Isso pode ser muito útil.

Trevoke
fonte
1
Eu envolvê-la em um módulo ter mesmo sentimento como inicialização de hash nativa:module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
asaaki
16

Reestruturando uma matriz

(a, b), c, d = [ [:a, :b ], :c, [:d1, :d2] ]

Onde:

a #=> :a
b #=> :b
c #=> :c
d #=> [:d1, :d2]

Usando essa técnica, podemos usar uma atribuição simples para obter os valores exatos que queremos da matriz aninhada de qualquer profundidade.

horseyguy
fonte
15

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 que inspectimprima um nome em vez de um número.

Não é algo que você precisa todos os dias, mas bastante útil quando precisa.

Apenas apaixonado
fonte
1
MyClass = Class.new Array do; def hi; 'hi'; end; endparece ser equivalente a class MyClass < Array; def hi; 'hi'; end; end.
Yfeldblum
1
Provavelmente mais verdadeiro do que eu pensava. Parece até que você pode herdar de uma variável e não apenas de uma constante. No entanto, a versão açucarada (segunda) não parece funcionar se você precisar construir o nome da classe em tempo de execução. (Baring eval, é claro.)
Justin Amor
Essa técnica é muito bem descrita no livro Metaprogramming Ruby .
Paul Pladijs
13

crie uma matriz de números consecutivos:

x = [*0..5]

define x para [0, 1, 2, 3, 4, 5]

horseyguy
fonte
Sim, mas não é tão curto e doce;)
horseyguy
2
concisão é objetivo, a legibilidade é questão de gosto e experiência
Alexey
O *operador splat ( ) basicamente chama to_aassim mesmo.
Matheus Moreira
13

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_readere attr_writersã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 como has_onee belongs_to.

Mas é bastante simples criar seus próprios truques de metaprogramação class_evalpara executar código gravado dinamicamente.

O exemplo a seguir permite que um objeto wrapper encaminhe certos métodos para um objeto interno:

class Wrapper
  attr_accessor :internal

  def self.forwards(*methods)
    methods.each do |method|
      define_method method do |*arguments, &block|
        internal.send method, *arguments, &block
      end
    end
  end

  forwards :to_i, :length, :split
end

w = Wrapper.new
w.internal = "12 13 14"
w.to_i        # => 12
w.length      # => 8
w.split('1')  # => ["", "2 ", "3 ", "4"]

O método Wrapper.forwardsutiliza símbolos para os nomes dos métodos e os armazena na methodsmatriz. Então, para cada um dos dados, usamos define_methodpara 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 .

TALlama
fonte
Desejo mergulhar de cabeça na metaprogramação em rubi. Você poderia fornecer algumas referências para começar (com exceção do link fornecido)? Livros também servem. Obrigado.
Chirantan 5/05/09
Serie videocasting de PragProg "O objeto do rubi Modelo e Metaprogramação" é uma boa introdução à programação meta usando Ruby: pragprog.com/screencasts/v-dtrubyom/...
Caffo
@Chirantan, dê uma olhada em Metaprogramming Ruby .
Paul Pladijs
12

use qualquer coisa que responda ===(obj)para comparações de casos:

case foo
when /baz/
  do_something_with_the_string_matching_baz
when 12..15
  do_something_with_the_integer_between_12_and_15
when lambda { |x| x % 5 == 0 }
  # only works in Ruby 1.9 or if you alias Proc#call as Proc#===
  do_something_with_the_integer_that_is_a_multiple_of_5
when Bar
  do_something_with_the_instance_of_Bar
when some_object
  do_something_with_the_thing_that_matches_some_object
end

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#callser um alias, como Proc#===no Ruby 1.9.

James A. Rosen
fonte
11

O binário "ruby" (pelo menos ressonância magnética) suporta muitos dos switches que tornaram perl one-liners bastante populares.

Significativos:

  • -n Configura um loop externo com apenas "gets" - que funciona magicamente com o nome de arquivo ou STDIN, configurando cada linha de leitura em $ _
  • -p Semelhante a -n, mas com um puts automático no final de cada iteração de loop
  • -uma chamada automática para .split em cada linha de entrada, armazenada em $ F
  • -i Editar arquivos de entrada no local
  • -l Chamada automática para .chomp na entrada
  • -e Executar um pedaço de código
  • -c Verifique o código fonte
  • -w Com avisos

Alguns exemplos:

# Print each line with its number:
ruby -ne 'print($., ": ", $_)' < /etc/irbrc

# Print each line reversed:
ruby -lne 'puts $_.reverse' < /etc/irbrc

# Print the second column from an input CSV (dumb - no balanced quote support etc):
ruby -F, -ane 'puts $F[1]' < /etc/irbrc

# Print lines that contain "eat"
ruby -ne 'puts $_ if /eat/i' < /etc/irbrc

# Same as above:
ruby -pe 'next unless /eat/i' < /etc/irbrc

# Pass-through (like cat, but with possible line-end munging):
ruby -p -e '' < /etc/irbrc

# Uppercase all input:
ruby -p -e '$_.upcase!' < /etc/irbrc

# Same as above, but actually write to the input file, and make a backup first with extension .bak - Notice that inplace edit REQUIRES input files, not an input STDIN:
ruby -i.bak -p -e '$_.upcase!' /etc/irbrc

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.

minaguib
fonte
10

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.

 %w(7 8 9 / 4 5 6 * 1 2 3 - 0 Clr = +).each do |btn|
    button btn, :width => 46, :height => 46 do
      method = case btn
        when /[0-9]/: 'press_'+btn
        when 'Clr': 'press_clear'
        when '=': 'press_equals'
        when '+': 'press_add'
        when '-': 'press_sub'
        when '*': 'press_times'
        when '/': 'press_div'
      end

      number.send(method)
      number_field.replace strong(number)
    end
  end

Eu falo mais sobre esse recurso no Blogging Shoes: o aplicativo Simple-Calc

CodingWithoutComments
fonte
Parece uma ótima maneira de abrir uma brecha na segurança.
mP.
4
Eu usaria símbolos sempre que possível.
reto
9

Engane alguma classe ou módulo dizendo que exigiu algo que realmente não era necessário:

$" << "something"

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:

$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
olegueret
fonte
Isso corrige problemas em que a gema A requer o foo-1.0.0 e a gema B exige o foo-1.0.1?
Andrew Grimm
Não, porque o código de "algo" não estará disponível: isso simula apenas que "algo" é necessário, mas na verdade não é necessário. $ "é uma matriz que contém os nomes dos módulos carregados por require (é usado por require para impedir o carregamento de módulos duas vezes). Portanto, se você usar isso para enganar gemas, isso causará um acidente quando as gemas tentarem usar o" algo "real código, porque ele não existirá.Você pode forçar a codificação de uma versão concreta de uma gema (por exemplo, foo-1.0.0), em vez da mais recente: docs.rubygems.org/read/chapter/4#page71
Olegueret 13/01/10
9

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:

rand(36**8).to_s(36) => "fmhpjfao"
rand(36**8).to_s(36) => "gcer9ecu"
rand(36**8).to_s(36) => "krpm0h9r"

Token de comprimento 6:

rand(36**6).to_s(36) => "bvhl8d"
rand(36**6).to_s(36) => "lb7tis"
rand(36**6).to_s(36) => "ibwgeh"
doença
fonte
9

Definindo um método que aceita qualquer número de parâmetros e apenas descarta todos eles

def hello(*)
    super
    puts "hello!"
end

O hellométodo acima só precisa puts "hello"aparecer na tela e chamar super- mas como a superclasse hellodefine 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.

horseyguy
fonte