Vraag Verborgen kenmerken van Ruby


Doorgaan met de "Verborgen kenmerken van ..." meme, laten we de minder bekende maar nuttige functies van Ruby-programmeertaal delen.

Probeer deze discussie te beperken met de kern Ruby, zonder Ruby on Rails dingen.

Zie ook:

(Alsjeblieft, gewoon een verborgen functie per antwoord.)

Dank je


160


oorsprong


antwoorden:


Van Ruby 1.9 Proc # === is een alias van Proc # call, wat betekent dat Proc-objecten kunnen worden gebruikt in case-statements zoals:

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

80



Peter Cooper heeft een goede lijst van Ruby tricks. Misschien is mijn favoriet dat zowel losse items als verzamelingen kunnen worden opgesomd. (Dat wil zeggen: behandel een niet-verzameling object als een verzameling die alleen dat object bevat.) Het ziet er als volgt uit:

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

76



Ik weet niet hoe verborgen dit is, maar ik heb het nuttig gevonden om een ​​hash uit een eendimensionale array te maken:

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

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

64



Een truc die ik leuk vind is om de splat te gebruiken (*) uitbreiding op andere objecten dan arrays. Hier is een voorbeeld van een wedstrijd met reguliere expressies:

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

Andere voorbeelden zijn:

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

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

54



Wauw, niemand noemde de flip-flop operator:

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

52



Een van de coole dingen over robijn is dat je methoden kunt aanroepen en code kunt uitvoeren op plaatsen waar andere talen zouden fronsen, zoals in methode- of klassendefinities.

Als u bijvoorbeeld een klasse wilt maken met een onbekende superklasse tot uitvoeringstijd, dat wil zeggen willekeurig is, kunt u het volgende doen:

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

end

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

Dit gebruikt de 1.9 Array#sample methode (alleen in 1.8.7 Array#choice), en het voorbeeld is behoorlijk gekunsteld, maar je kunt de kracht hier zien.

Een ander cool voorbeeld is de mogelijkheid om standaardparameterwaarden op te slaan die niet vast zijn (zoals andere talen vaak vragen):

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

Natuurlijk is het probleem met het eerste voorbeeld dat het wordt geëvalueerd op het moment van definitie, niet op beltijd. Dus, als eenmaal een superklasse is gekozen, blijft het die superklasse voor de rest van het programma.

In het tweede voorbeeld echter elke keer dat u belt do_something_at, de at variabele is de tijd dat de methode werd aangeroepen (nou ja, heel dichtbij)


49



Nog een kleinigheidje - converteer een Fixnum in elke base tot 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"

En zoals Huw Walters al opmerkte, is het omrekenen van de andere manier net zo eenvoudig:

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

47



Hashes met standaardwaarden! Een array in dit geval.

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

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

Zeer nuttig in metaprogrammering.


40



Download Ruby 1.9-bron en probleem make golf, dan kun je dit soort dingen doen:

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"

Lees de golf_prelude.c voor meer nette dingen weg verstoppen.


39



Een andere leuke toevoeging in 1.9 Proc-functionaliteit is Proc # curry, waarmee je een Proc accepterende n-argumenten in één accepteren n-1 kunt veranderen. Hier wordt het gecombineerd met de Proc # === tip die ik hierboven noemde:

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

38