Caratteristiche nascoste di Ruby


160

Continuando il meme "Funzioni nascoste di ...", condividiamo le funzioni meno note ma utili del linguaggio di programmazione Ruby.

Cerca di limitare questa discussione con il nucleo di Ruby, senza alcun materiale su Ruby on Rails.

Guarda anche:

(Per favore, solo una funzione nascosta per risposta.)

Grazie


dovrebbe essere wiki della comunità
SilentGhost il

Risposte:


80

Da Ruby 1.9 Proc # === è un alias di Proc # call, il che significa che gli oggetti Proc possono essere usati in questi casi:

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

1
In realtà ho scritto una gemma ad un certo punto per farlo, ma il mio codice era (a) un casino e (b) lento. Sono molto contento che la funzionalità sia diventata fondamentale.
James A. Rosen,

76

Peter Cooper ha una buona lista di trucchi per Ruby. Forse il mio preferito è consentire l'enumerazione di singoli articoli e collezioni. (Cioè, tratta un oggetto non di raccolta come una raccolta contenente solo quell'oggetto.) È simile al seguente:

[*items].each do |item|
  # ...
end

38
Una forma più esplicita (e quindi più gradevole) di questo è Array (items) .each
mislav

Se itemsè una stringa non è necessario racchiuderla tra [*…]. String.each non scorre i caratteri come alcuni potrebbero aspettarsi. Ritorna da solo al blocco.
mxcl,

A che cosa servirebbe mai? Solo curioso.
Ed S.

1
@Ed: è bello se stai scrivendo un metodo e vuoi consentire all'utente del metodo di passare un elenco varargs o un array.
James A. Rosen,

64

Non so quanto sia nascosto, ma l'ho trovato utile quando è necessario creare un hash da un array unidimensionale:

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

Hash[*fruit]    
=> {"apple"=>"red", "banana"=>"yellow"}

Si noti che Hash[ [["apple","red"], ["banana","yellow"] ]produce lo stesso risultato.
Marc-André Lafortune,

54

Un trucco che mi piace è usare l' *espansore splat ( ) su oggetti diversi da Array. Ecco un esempio di una corrispondenza di espressioni regolari:

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

Altri esempi includono:

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

Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom

13
Per inciso, per i curiosi, questo funziona chiamando implicitamente to_a sul bersaglio dello splat.
Bob Aman,

1
Se non sei interessato alla partita, puoi averlo 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
Entrambi i buoni trucchi, ma ci deve essere un punto in cui è troppa magia, giusto ?!
tomafro,

1
@Andrew, hai considerato che quella partita può tornare a zero? nil non ha metodo []
Alexey,

52

Wow, nessuno ha menzionato l'operatore di infradito:

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end

11
Giusto ... qualcuno dovrà spiegarmelo. Funziona, ma non riesco a capire perché.
Bob Aman,

12
L'operatore flip flop è un statefull if. Il suo stato passa a vero non appena i == 3e passa a falso dopo i != 3 e i == 15. Simile a un infradito: en.wikipedia.org/wiki/Flip-flop_%28electronics%29
Konstantin Haase,

1
Non la definirei esattamente una caratteristica nascosta, un gran fastidio. Ricordo la prima volta che mi è stato presentato in #Ruby su Freenode, anni fa; Ho usato praticamente ogni singola caratteristica di Ruby ad un certo punto tranne questa.
ELLIOTTCABLE

1
Non lo definirei un fastidio, è solo qualcosa che non hai usato. Lo uso e può ridurre bene il codice, specialmente quando sto prendendo blocchi di linee da file basati su alcuni criteri.
Tin Man,

49

Una delle cose più belle di ruby ​​è che puoi chiamare metodi ed eseguire codice in luoghi in cui altre lingue potrebbero essere disapprovate, come nelle definizioni di metodi o classi.

Ad esempio, per creare una classe che ha una superclasse sconosciuta fino al runtime, ovvero è casuale, è possibile effettuare le seguenti operazioni:

class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample

end

RandomSubclass.superclass # could output one of 6 different classes.

Questo utilizza il Array#samplemetodo 1.9 (solo in 1.8.7, vediArray#choice ), e l'esempio è abbastanza elaborato ma puoi vedere il potere qui.

Un altro esempio interessante è la possibilità di inserire valori di parametri predefiniti non fissi (come spesso richiedono altre lingue):

def do_something_at(something, at = Time.now)
   # ...
end

Naturalmente il problema con il primo esempio è che viene valutato al momento della definizione, non al momento della chiamata. Quindi, una volta che una superclasse è stata scelta, rimane quella superclasse per il resto del programma.

Tuttavia, nel secondo esempio, ogni volta che chiami do_something_at, la atvariabile sarà l'ora in cui è stato chiamato il metodo (beh, molto molto vicino ad esso)


2
Nota: Array # rand è fornito da ActiveSupport che è possibile utilizzare al di fuori di Rails con la stessa facilità direquire 'activesupport'
rfunduk

La scelta dell'array # è in 1.8.7
Josh Lee

24
La scelta dell'array # è solo 1.8.7 ! Non usarlo, è andato in 1.9 e sarà andato in 1.8.8. Usa #sample
Marc-André Lafortune il

python: class DictList ([dict, list] [random.randint (0,1)]): pass
Anurag Uniyal

def do_something_at (qualcosa, at = lambda {Time.now}) at.call #now assegnare dinamicamente la fine del tempo
Jack Kinsella,

47

Un'altra piccola funzionalità: converti a Fixnumin qualsiasi base fino a 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 come ha commentato Huw Walters, convertire dall'altra parte è altrettanto semplice:

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

1
E per completezza, String#to_s(base)può essere usato per riconvertire in un numero intero; "1001001100101100000001011010010".to_i(2), "499602d2".to_i(16)ecc. tutti restituiscono l'originale Fixnum.
Huw Walters,

40

Hash con valori predefiniti! Un array in questo caso.

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

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

Molto utile nella metaprogrammazione.


1
si vero. L'hash di Ruby può accettare l'operatore '<<' se c'è già un valore predefinito assegnato con '=' (non importa anche se è un'assegnazione vuota) altrimenti l'hash non accetterà '<<'. CMIIW
mhd,

39

Scarica la fonte di Ruby 1.9 e rilasciala make golf, quindi puoi fare cose del genere:

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"

Leggi golf_prelude.cper altre cose pulite che si nascondono.


38

Un'altra aggiunta divertente nella funzionalità Proc 1.9 è il curry Proc # che consente di trasformare un Proc che accetta n argomenti in uno che accetta n-1. Qui è combinato con il suggerimento Proc # === che ho menzionato sopra:

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

35

Operatori booleani su valori non booleani.

&& e ||

Entrambi restituiscono il valore dell'ultima espressione valutata.

Questo è il motivo per cui ||=aggiornerà la variabile con il valore restituito espressione sul lato destro se la variabile non è definita. Questo non è esplicitamente documentato, ma conoscenza comune.

Tuttavia, &&=non è abbastanza conosciuto.

string &&= string + "suffix"

è equivalente a

if string
  string = string + "suffix"
end

È molto utile per operazioni distruttive che non dovrebbero procedere se la variabile non è definita.


2
Più precisamente, string &&= string + "suffix" equivale a string = string && string + "suffix". Quello &&e ||restituire il loro secondo argomento è discusso in PickAx, p. 154 (Parte I - Sfaccettature di rubino, espressioni, esecuzione condizionale).
Richard Michael,

29

La funzione Symbol # to_proc fornita da Rails è davvero interessante.

Invece di

Employee.collect { |emp| emp.name }

Tu puoi scrivere:

Employee.collect(&:name)

Questo è, apparentemente, un "ordine di grandezza più lento" rispetto all'utilizzo di un blocco. igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri
Charles Roper

L'ho appena provato e ho scoperto che non c'erano differenze significative tra i due. Non sono sicuro da dove provenga questo "ordine di grandezza". (Usando Ruby 1.8.7)
Matt Grande,

1
Farlo al di fuori di Rails è anche utile e può essere fatto require 'activesupport'poiché è in realtà da dove provengono la maggior parte di questi helper.
rfunduk,

8
questo era lento a causa dell'implementazione di active_support, cioè accettava più argomenti in modo da poter fare merda come (1..10) .inject &: *, ma il caso d'uso principale era spesso solo chiamare un metodo su ciascun membro di un raccolta ad es.% w (la volpe bruno veloce) .map &: upcase. a partire da 1.8.7 è il rubino core e le prestazioni sono ragionevoli.
Steve Graham,

4
@thenduks: E può essere fatto senza l'aiuto di activesupport in ruby ​​1.8.7 e 1.9.
Andrew Grimm,

28

Un ultimo: in rubino puoi usare qualsiasi carattere che desideri delimitare le stringhe. Prendi il seguente codice:

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

Se non vuoi sfuggire alle doppie virgolette all'interno della stringa, puoi semplicemente usare un delimitatore diverso:

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

Oltre a evitare di dover sfuggire ai delimitatori, puoi utilizzare questi delimitatori per stringhe multilinea più belle:

sql = %{
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
}

19
Non alcun carattere, ma è ancora piuttosto fresco. Funziona anche con altri letterali:% () /% {} /% [] /% <> /% || % r () /% r {} /% r [] /% r <> /% r || % w () /% w {} /% w [] /% w <> /% w ||
Bo Jeanes

C'è anche la sintassi del documento herenow: << BLOCK ... BLOCK, che mi piace usare per cose come istruzioni SQL multilinea ecc.
Martin T.

26

Trovo che usare il comando define_method per generare dinamicamente metodi sia abbastanza interessante e non così noto. Per esempio:

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

Il codice sopra usa il comando 'define_method' per creare dinamicamente i metodi da "press1" a "press9". Invece di digitare tutti i 10 metodi che contengono essenzialmente lo stesso codice, il comando define method viene utilizzato per generare questi metodi al volo, se necessario.


4
L'unico problema con define_method è che non consente il passaggio di blocchi come parametri in ruby ​​1.8. Vedi questo post sul blog per una soluzione alternativa.
Andrew Grimm,

26

Utilizzare un oggetto Range come un elenco pigro infinito:

Inf = 1.0 / 0

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

Maggiori informazioni qui: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/


Lazy_select nell'articolo collegato è molto pulito.
Joseph Weissman,

Questo è davvero fantastico. Mi piace come Infinity sia un float, in questo modo quando ho provato questo: (-Inf..Inf) .take (4) ha sollevato un (logicamente coerente) non può iterare dall'errore float. : D
zachaysan,

23

module_function

I metodi del modulo dichiarati come module_function creeranno copie di se stessi come metodi di istanza privata nella classe che include il modulo:

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 si utilizza module_function senza alcun argomento, tutti i metodi del modulo che seguono l'istruzione module_function diventeranno automaticamente module_functions stessi.

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!'

4
Se vuoi solo dichiarare metodi privati ​​nei moduli, usa semplicemente la parola chiave privata. Oltre a rendere privato il metodo nelle classi che includono il modulo, module_function copia il metodo nell'istanza del modulo. Nella maggior parte dei casi questo non è quello che vuoi.
Tomafro,

So che puoi semplicemente usare privato. Ma questa è una domanda sulle caratteristiche nascoste di Ruby. E penso che la maggior parte delle persone non abbia mai sentito parlare di module_function (me compreso) fino a quando non lo vedono nel documento e iniziano a giocarci.
Newtonapple,

Un'alternativa all'utilizzo module_function(secondo modo) è semplicemente usare extend self(che sembra piuttosto carino: D)
J -_- L


21

Attenzione: questo articolo è stato votato come il primo hack più orrendo del 2008 , quindi usalo con cura. In realtà, evitatelo come la peste, ma è certamente nascosto Ruby.

I superatori aggiungono nuovi operatori a Ruby

Hai mai desiderato un operatore di stretta di mano super-segreto per un'operazione unica nel tuo codice? Ti piace giocare a code golf? Prova operatori come - ~ + ~ - o <--- Quest'ultimo è usato negli esempi per invertire l'ordine di un articolo.

Non ho nulla a che fare con il Progetto Superatori oltre ad ammirarlo.


19

Sono in ritardo alla festa, ma:

Puoi facilmente prendere due array di uguale lunghezza e trasformarli in un hash con un array che fornisce le chiavi e l'altro i valori:

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

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

(Funziona perché Array # zip "zippa" i valori dei due array:

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

E Hash [] può prendere proprio un tale array. Ho visto anche le persone fare questo:

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

Il che produce lo stesso risultato, ma lo splat e l'appiattimento sono del tutto inutili - forse non lo erano in passato?)


3
Questo non è stato documentato per molto tempo (vedi redmine.ruby-lang.org/issues/show/1385 ). Nota che questa nuova forma è nuova per Ruby 1.8.7
Marc-André Lafortune il

19

Hash auto-vivificanti in 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 } } }

Questo può essere dannatamente utile.


1
Lo avvolgo in un modulo per avere la stessa sensazione di init hash nativo:module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
asaaki

16

Distruzione di una matrice

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

Dove:

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

Usando questa tecnica possiamo usare una semplice assegnazione per ottenere i valori esatti che vogliamo dall'array nidificato di qualsiasi profondità.


15

Class.new()

Crea una nuova classe in fase di esecuzione. L'argomento può essere una classe da cui derivare e il blocco è il corpo della classe. Puoi anche cercare const_set/const_get/const_defined?di registrare correttamente la tua nuova classe, in modo che inspectvenga stampato un nome anziché un numero.

Non qualcosa di cui hai bisogno ogni giorno, ma abbastanza utile quando lo fai.


1
MyClass = Class.new Array do; def hi; 'hi'; end; endsembra essere equivalente a class MyClass < Array; def hi; 'hi'; end; end.
yfeldblum,

1
Probabilmente più vero di quanto avessi pensato. Sembra persino che tu possa ereditare da una variabile piuttosto che solo da una costante. Tuttavia, la versione zuccherata (seconda) non sembra funzionare se è necessario costruire il nome della classe in fase di esecuzione. (Baring eval, ovviamente.)
Justin Love,

Questa tecnica è abbastanza ben descritta nel libro Metaprogramming Ruby .
Paul Pladijs,

13

creare una matrice di numeri consecutivi:

x = [*0..5]

imposta x su [0, 1, 2, 3, 4, 5]


Sì, ma non è così breve e dolce;)
Horseyguy,

2
la terseness è oggettiva, la leggibilità è questione di gusto ed esperienza
Alexey,

L' *operatore splat ( ) praticamente chiama to_acomunque.
Matheus Moreira,

13

Gran parte della magia che vedi in Rubyland ha a che fare con la metaprogrammazione, che è semplicemente scrivere codice che scrive codice per te. Ruby attr_accessor, attr_readere attr_writersono tutti semplici metaprogrammazione, in quanto creano due metodi in una riga, a seguito di un modello standard. Rails esegue molte metaprogrammazioni con i loro metodi di gestione delle relazioni come has_oneebelongs_to .

Ma è abbastanza semplice creare i tuoi trucchi di metaprogrammazione usando class_evalper eseguire codice scritto dinamicamente.

L'esempio seguente consente a un oggetto wrapper di inoltrare determinati metodi insieme a un oggetto 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"]

Il metodo Wrapper.forwardsaccetta i simboli per i nomi dei metodi e li memorizza nella methodsmatrice. Quindi, per ciascuno di quelli indicati, usiamodefine_method per creare un nuovo metodo il cui compito è di inviare il messaggio, inclusi tutti gli argomenti e i blocchi.

Una grande risorsa per i problemi di metaprogrammazione è il motivo per cui "Il vedere chiaramente la metaprogrammazione" di Lucky Stiff .


Vorrei immergermi prima nella metaprogrammazione nel rubino. Potresti fornire alcuni riferimenti per iniziare (diverso dal link indicato)? Anche i libri lo faranno. Grazie.
Chirantan,

La serie di videocast di PragProg "The Ruby Object Model and Metaprogramming" è una buona introduzione alla meta programmazione usando ruby: pragprog.com/screencasts/v-dtrubyom/…
caffo,

@Chirantan, dai un'occhiata a Metaprogramming Ruby .
Paul Pladijs,

12

usa tutto ciò che risponde ai ===(obj)confronti dei casi:

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 quindi Class), Regexp, Date, e molte altre classi definiscono un metodo di istanza: === (altri), e possono tutti essere usati.

Grazie a Farrel per il promemoria di Proc#callessere aliasati come Proc#===in Ruby 1.9.


11

Il binario "ruby" (almeno la risonanza magnetica) supporta molti degli switch che hanno reso perl una linea piuttosto popolare.

Significativi:

  • -n Imposta un ciclo esterno con solo "get" - che funziona magicamente con il nome file o STDIN dato, impostando ogni riga di lettura in $ _
  • -p Simile a -n ma con una puts automatica alla fine di ogni iterazione di loop
  • -a Chiamata automatica a .split su ogni linea di input, memorizzata in $ F
  • -i Modifica i file di input sul posto
  • -l Chiamata automatica a .chomp su input
  • -e Esegue un pezzo di codice
  • -c Controlla il codice sorgente
  • -w Con avvertenze

Qualche esempio:

# 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

Sentiti libero di utilizzare Google "ruby one-liners" e "perl one-liners" per tonnellate di esempi più utilizzabili e pratici. In sostanza ti permette di usare il rubino come un sostituto abbastanza potente di awk e sed.


10

Il metodo send () è un metodo generico che può essere utilizzato su qualsiasi classe o oggetto in Ruby. Se non sovrascritto, send () accetta una stringa e chiama il nome del metodo di cui viene passata la stringa. Ad esempio, se l'utente fa clic sul pulsante "Clr", la stringa "press_clear" verrà inviata al metodo send () e verrà chiamato il metodo "press_clear". Il metodo send () consente un modo divertente e dinamico di chiamare funzioni in 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

Parlo di più di questa funzione in Scarpe da blog: l'applicazione Simple-Calc


Sembra un ottimo modo per aprire una falla di sicurezza.
mP.

4
Userei i simboli ove possibile.
reto

9

Imbrogliamo qualche classe o modulo dicendo che ha richiesto qualcosa che in realtà non ha richiesto:

$" << "something"

Questo è utile ad esempio quando si richiede A che a sua volta richiede B ma non abbiamo bisogno di B nel nostro codice (e A non lo userà nemmeno attraverso il nostro codice):

Ad esempio, Backgroundrb's bdrb_test_helper requires 'test/spec', ma non lo usi affatto, quindi nel tuo codice:

$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")

Questo risolve i problemi in cui la gemma A richiede foo-1.0.0 e la gemma B richiede foo-1.0.1?
Andrew Grimm,

No perché il codice di "qualcosa" non sarà disponibile: questo simula solo la necessità di "qualcosa", ma in realtà non lo richiede. $ "è un array che contiene i nomi dei moduli caricati da request (viene utilizzato da request per impedire il caricamento dei moduli due volte). Quindi, se lo usi per ingannare le gemme, ciò produrrà un arresto anomalo quando le gemme tenteranno di usare il vero" qualcosa " codice, perché non esisterà. Potresti invece voler forzare la codifica di una versione concreta di una gemma (ad esempio foo-1.0.0), anziché l'ultima: docs.rubygems.org/read/chapter/4#page71
Olegueret,

9

Fixnum#to_s(base)può essere davvero utile in alcuni casi. Uno di questi casi sta generando token univoci casuali (pseudo) convertendo il numero casuale in stringa usando la base di 36.

Token di lunghezza 8:

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

Token di lunghezza 6:

rand(36**6).to_s(36) => "bvhl8d"
rand(36**6).to_s(36) => "lb7tis"
rand(36**6).to_s(36) => "ibwgeh"

9

Definire un metodo che accetta un numero qualsiasi di parametri e li scarta tutti

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

Il hellometodo sopra deve solo essere visualizzato puts "hello"sullo schermo e chiamare super, ma poiché la superclasse hellodefinisce i parametri deve farlo anche lui, tuttavia poiché non è necessario utilizzare i parametri stessi, non deve dare loro un nome.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.