63 votes

Idiomes de rubis courants

Une chose que j'aime à propos de ruby, c'est que la plupart du temps c'est très lisible de la langue (qui est excellent pour l'auto-documentation du code)

Toutefois, inspiré par cette question: http://stackoverflow.com/questions/609612/ruby-code-explained et la description de la façon dont ||= travaux en ruby, je pensais à la ruby idiomes je ne l'utilise pas, car honnêtement, je n'ai pas entièrement grok.

Donc ma question est semblable à l'exemple de l'référencé question, quoi de commun, mais pas évident, ruby idiomes ai-je besoin d'être conscient de la être un de vraiment compétent ruby programmeur?

Par la façon dont, à partir de l'référencé question

a ||= b

est équivalent à

if a == nil || a == false
  a = b
end

(Merci à Ian Terrell pour la correction)

Edit: Il s'avère que ce point n'est pas totalement prête pas à controverse. La bonne extension est en fait

(a || (a = (b)))

Voir ces liens pour pourquoi:

Grâce à Jörg W Mittag pour le rappeler.

50voto

rampion Points 38697

La magie si la clause qui permet au même fichier de servir comme une bibliothèque ou un script:

if __FILE__ == $0
  # this library may be run as a standalone script
end

L'emballage et le déballage des tableaux:

# put the first two words in a and b and the rest in arr
a,b,*arr = *%w{a dog was following me, but then he decided to chase bob}
# this holds for method definitions to
def catall(first, *rest)
  rest.map { |word| first + rest }
end
catall( 'franken', 'stein', 'berry', 'sense' ) #=> [ 'frankenstein', 'frankenberry', 'frankensense' ]

Le syntatical de sucre pour le hachage comme des arguments de méthode

this(:is => :the, :same => :as)
this({:is => :the, :same => :as})

Hachage des initialiseurs:

# this
animals = Hash.new { [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {}
# is not the same as this
animals = Hash.new { |_animals, type| _animals[type] = [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {:squirrels=>[:Rocket, :Secret], :dogs=>[:Scooby, :Scrappy, :DynoMutt]}

métaclasse syntaxe

x = Array.new
y = Array.new
class << x
  # this acts like a class definition, but only applies to x
  def custom_method
     :pow
  end
end
x.custom_method #=> :pow
y.custom_method # raises NoMethodError

les variables d'instance de classe

class Ticket
  @remaining = 3
  def self.new
    if @remaining > 0
      @remaining -= 1
      super
    else
      "IOU"
    end
  end
end
Ticket.new #=> Ticket
Ticket.new #=> Ticket
Ticket.new #=> Ticket
Ticket.new #=> "IOU"

Les blocs, les procs, et les lambdas. Vivre et respirer.

 # know how to pack them into an object
 block = lambda { |e| puts e }
 # unpack them for a method
 %w{ and then what? }.each(&block)
 # create them as needed
 %{ I saw a ghost! }.each { |w| puts w.upcase }
 # and from the method side, how to call them
 def ok
   yield :ok
 end
 # or pack them into a block to give to someone else
 def ok_dokey_ok(&block)
    ok(&block)
    block[:dokey] # same as block.call(:dokey)
    ok(&block)
 end
 # know where the parentheses go when a method takes arguments and a block.
 %w{ a bunch of words }.inject(0) { |size,w| size + 1 } #=> 4
 pusher = lambda { |array, word| array.unshift(word) }
 %w{ eat more fish }.inject([], &pusher) #=> ['fish', 'more', 'eat' ]

11voto

VonC Points 414372

Ce diaporama est assez complet sur les principaux idiomes de Ruby, comme dans:

  • Échangez deux valeurs:

    x, y = y, x

  • Paramètres qui, s'ils ne sont pas spécifiés, prennent une valeur par défaut

    def somemethod (x, y = nil)

  • Met en place des paramètres parasites dans un tableau

    def substitute (re, str, * rest)

Etc...

8voto

Chubas Points 8670

Certains plus d'expressions idiomatiques:

L'utilisation de l' %w, %r et %( délimiteurs

%w{ An array of strings %}
%r{ ^http:// }
%{ I don't care if the string has 'single' or "double" strings }

Type de comparaison dans le cas des déclarations

def something(x)
  case x
    when Array
      # Do something with array
    when String
      # Do something with string
    else
      # You should really teach your objects how to 'quack', don't you?
  end
end

... et de l'ensemble de l'abus de l' === méthode dans le cas des déclarations

case x
  when 'something concrete' then ...
  when SomeClass then ...
  when /matches this/ then ...
  when (10...20) then ...
  when some_condition >= some_value then ...
  else ...
end

Quelque chose qui doit être naturelle à Rubyists, mais peut-être pas tant que les personnes en provenance d'autres langues: l'utilisation de l' each en faveur de l' for .. in

some_iterable_object.each{|item| ... }

En Ruby 1.9+, Rails, ou en bidouillant le Symbole#to_proc méthode, cela devient de plus en plus idiome populaire:

strings.map(&:upcase)

Conditionnel méthode/définition de constante

SOME_CONSTANT = "value" unless defined?(SOME_CONSTANT)

Méthodes de requête et destructrice (bang) méthodes

def is_awesome?
  # Return some state of the object, usually a boolean
end

def make_awesome!
  # Modify the state of the object
end

Implicite splat paramètres

[[1, 2], [3, 4], [5, 6]].each{ |first, second| puts "(#{first}, #{second})" }

7voto

ucron Points 1884

Je suggérerais de lire à travers le code des plugins populaires et bien conçus ou des bijoux de gens que vous admirez et respectez.

Quelques exemples que j'ai rencontrés:

 if params[:controller] == 'discussions' or params[:controller] == 'account'
  # do something here
end
 

correspond à

 if ['account', 'discussions'].include? params[:controller]
  # do something here
end
 

qui plus tard serait refactored à

 if ALLOWED_CONTROLLERS.include? params[:controller]
  # do something here
end
 

7voto

Daemin Points 5651

J'aime ça:

 str = "Something evil this way comes!"
regexp = /(\w[aeiou])/

str[regexp, 1] # <- This
 

Ce qui équivaut (approximativement) à:

 str_match = str.match(regexp)
str_match[1] unless str_match.nil?
 

Ou du moins c'est ce que j'ai utilisé pour remplacer ces blocs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X