Frage

Eine Sache, die ich Liebe über ruby ist, dass es meist einen sehr gut lesbaren Sprache geschrieben (das ist toll für die selbst-Dokumentation-code)

Jedoch, angeregt durch diese Frage: Ruby-Code erklärt und die Beschreibung, wie ||= funktioniert in ruby, ich dachte über die ruby Redewendungen, die ich nicht verwenden, denn ehrlich gesagt glaube ich nicht vollständig Begriffen Sie.

Meine Frage ist also, ähnlich dem Beispiel aus der referenzierten Frage, welche gemeinsamen, aber nicht offensichtlich, ruby Redewendungen brauche ich, um bewusst sein, um ein wirklich beherrschen ruby-Programmierer?

Durch die Art und Weise, aus der referenzierten Frage

a ||= b 

ist äquivalent zu

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

(Dank an Ian Terrell für die Korrektur)

Edit: Es stellt sich heraus, dieser Punkt ist nicht ganz unumstritten.Die korrekte Erweiterung ist in der Tat

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

Siehe diese links für warum:

Herzlichen Dank an Jörg W Mittag für den Hinweis.

War es hilfreich?

Lösung

Die Magie, wenn Klausel, die die gleiche Datei dient als Bibliothek oder einem Skript können:

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

Ein- und Auspacken Arrays:

# 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 + word }
end
catall( 'franken', 'stein', 'berry', 'sense' ) #=> [ 'frankenstein', 'frankenberry', 'frankensense' ]

Der syntatical Zucker für Hashes als Methodenargumente

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

Hash initializers:

# 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]}

metaclass Syntax

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

Klasse Instanzvariablen

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"

Blöcke, Procs und Lambda. Leben und sie atmen.

 # 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
 %w{ 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' ]

Andere Tipps

Die Diashow ist ganz vollständig auf den wichtigsten Ruby-Idiomen, wie in:

  • Swap zwei Werte:

    x, y = y, x

  • Parameter, die, wenn nicht anders angegeben, auf einigen Standardwerten nehmen

    def somemethod(x, y=nil)

  • Batches bis Fremd Parameter in ein Array

    def substitute(re, str, *rest)

Und so weiter ...

Einige weitere Idiome:

Die Verwendung der %w, %r und %( Begrenzer

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

Typ Vergleich in case-Anweisungen

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

... und die allgemeine Missbrauch der === Methode in case-Anweisungen

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

Etwas, das zu Rubyisten natürlich aussehen soll, aber vielleicht nicht so zu Menschen aus anderen Sprachen kommen: die Verwendung von each für for .. in

some_iterable_object.each{|item| ... }

In Ruby 1.9+, Rails oder durch das Symbol # to_proc Methode Patchen, diese wird immer beliebtes Idiom:

strings.map(&:upcase)

Bedingte Methode / constant Definition

SOME_CONSTANT = "value" unless defined?(SOME_CONSTANT)

Abfrageverfahren und destruktiv (Bang) Methods

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

def make_awesome!
  # Modify the state of the object
end

Implizite Splat Parameter

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

Ich mag diese:

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

str[regexp, 1] # <- This

das ist (grob) entspricht:

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

Oder zumindest das ist, was ich verwendet habe, solche Blöcke zu ersetzen.

Ich würde vorschlagen, das Lesen durch den code der beliebten und gut gestaltet plugins oder Edelsteine von Menschen, die Sie respektieren und bewundern.

Einige Beispiele habe ich in laufen:

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

entsprechend

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

die später umgestaltet werden, um

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

Hier sind ein paar, aus verschiedenen Quellen gekeult:

verwenden „wenn nicht“ und „bis“ statt „wenn nicht“ und „zwar nicht“. Versuchen Sie, nicht zu verwenden, „es sei denn“ wenn eine „else“ Bedingung existiert, though.

Denken Sie daran, Sie mehrere Variablen auf einmal zuweisen können:

a,b,c = 1,2,3

und tauschen sogar Variable ohne Temp:

a,b = b,a

Verwenden Hinter conditionals gegebenenfalls z.

do_something_interesting unless want_to_be_bored?

Beachten Sie eine häufig verwendete, aber nicht sofort offensichtlich (zumindest für mich) Art und Weise Klassenmethoden zu definieren:

class Animal
  class<<self
    def class_method
      puts "call me using Animal.class_method"
    end
  end
end

Einige Referenzen:

  

Durch die Art und Weise, von dem referenzierten   Frage

a ||= b 
     

entspricht

if a == nil   
  a = b 
end

Das ist subtil falsch, und ist eine Quelle von Fehlern in Neulingen Ruby-Anwendungen.

Da sowohl (und nur) nil und false zu einem boolean false auswerten, a ||= b ist eigentlich (fast *) entspricht:

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

Oder zu umschreiben es mit einem anderen Ruby-Idiom:

a = b unless a

(* Da jede Aussage einen Wert hat, sind diese nicht technisch gleichwertig a ||= b. Aber wenn Sie nicht auf den Wert der Aussage verlassen, werden Sie keinen Unterschied sehen.)

Ich halte eine Wiki-Seite, die einige Ruby-Idiome und Formatierungen umfasst:

https://github.com/tokland/tokland/wiki/RubyIdioms

Ich vergesse immer die genaue Syntax dieser Stenografie wenn else-Anweisung (und der Name des Betreibers Kommentar jemand.?) Ich denke, es ist weit außerhalb von Ruby verwendet wird, aber falls jemand anderes die Syntax hier ist sie:

refactor < 3 ? puts("No need to refactor YET") : puts("You need to refactor this into a  method")

expandiert nach

if refactor < 3
  puts("No need to refactor YET")
else
  puts("You need to refactor this into a  method")
end

update

genannt ternärer Operator:

Rückkehr myvar? myvar.size: 0

Sie können Objekt mit Marshalling leicht deep. - genommen aus der Sprache Ruby-Programmierung

def deepcopy(o)
  Marshal.load(Marshal.dump(o))
end
  

Beachten Sie, dass Dateien und E / A-Streams, wie   sowie Verfahren und Bindungsobjekten,   zu dynamisch sind gemarshallt zu werden; Dort   wäre keine zuverlässige Möglichkeit zur Wiederherstellung   ihr Zustand ist.

a = (b && b.attribute) || "default"

ist in etwa:

if ( ! b.nil? && ! b == false) && ( ! b.attribute.nil? && ! b.attribute.false) a = b
else a = "default"

Ich benutze dies, wenn b eine Aufzeichnung ist, die können oder auch nicht gefunden worden, und ich brauche eine seiner Eigenschaften zu erhalten.

Ich mag, wie If-then-elses oder fall wenn verkürzt werden kann, weil sie einen Wert zurückgeben:

if test>0
  result = "positive"
elsif test==0
  result = "zero"
else
  result = "negative"
end

könnte rewriten

result = if test>0
  "positive"
elsif test==0
  "zero"
else
  "negative"
end

Das gleiche könnte angewendet werden, Fall-wenn:

result = case test
when test>0 ; "positive"
when test==0 ; "zero"
else "negative"
end

Array.pack und String.unpack für die Arbeit mit binären Dateien:

# extracts four binary sint32s to four Integers in an Array
data.unpack("iiii") 

Methode fehlt Magick

class Dummy  
  def method_missing(m, *args, &block)  
    "You just called method with name #{m} and arguments- #{args}"  
  end  
end

Dummy.new.anything(10, 20)
=> "You just called method with name anything and arguments- [10, 20]"

Wenn Sie Methoden aufrufen, die in Ruby Objekte existiert nicht, wird Ruby-Interpreter-Methode ‚method_missing‘ genannt nennen, wenn seine definiert, können Sie Benutzer dies für einige Tricks, wie api Wrapper schreiben, oder dsl, wo Sie don t wissen alle Methoden und Parameter-Namen

Nizza Frage!

Wie ich denke, die intuitiver und schneller ist der Code, eine bessere Software bauen wir. Ich werde Ihnen zeigen, wie ich meine Gedanken mit Ruby in kleinem Code-Schnipsel auszudrücken. Lesen Sie mehr

Karte

Wir können die Karten Verfahren auf verschiedene Arten verwendet werden:

user_ids = users.map { |user| user.id }

Oder:

user_ids = users.map(&:id)

Beispiel:

Wir können rand Methode verwenden:

[1, 2, 3][rand(3)]

Shuffle:

[1, 2, 3].shuffle.first

Und die idiomatische, einfache und einfachste Art und Weise ... Probe!

[1, 2, 3].sample

Doppelrohr Equals / memoization

Wie Sie in der Beschreibung sagen, können wir memoization verwenden:

some_variable ||= 10
puts some_variable # => 10

some_variable ||= 99
puts some_variable # => 10

Statische Methode / Klasse Methode

Ich mag Klassenmethoden verwenden, halte ich es für eine wirklich idiomatische Weg zu schaffen und Nutzungsklassen:

GetSearchResult.call(params)

Einfach. Schön. Intuitiv. Was passiert im Hintergrund?

class GetSearchResult
  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # ... your code here ...
  end
end

Für weitere Informationen idiomatischen Ruby-Code zu schreiben, lesen hier

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top