125 Stimmen

Ruby optionale Parameter

Wenn ich eine Ruby-Funktion wie folgt definiere:

def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )

Wie kann ich sie aufrufen und nur die ersten 2 und den letzten Argumente übergeben? Warum ist etwas wie

ldap_get( base_dn, filter, , X)

nicht möglich oder wenn es möglich ist, wie kann es gemacht werden?

0voto

Singularity Punkte 251

Kürzlich habe ich einen Weg gefunden, das zu umgehen. Ich wollte eine Methode in der Array-Klasse mit einem optionalen Parameter erstellen, um Elemente im Array zu behalten oder zu verwerfen.

Die Art und Weise, wie ich das simuliert habe, bestand darin, ein Array als Parameter zu übergeben und dann zu überprüfen, ob der Wert an diesem Index nil war oder nicht.

class Array
  def ascii_to_text(params)
    param_len = params.length
    if param_len > 3 or param_len < 2 then raise "Ungültige Anzahl von Argumenten #{param_len} für 2 || 3." end
    bottom  = params[0]
    top     = params[1]
    keep    = params[2]
    if keep.nil? == false
      if keep == 1
        self.map{|x| if x >= bottom and x <= top then x = x.chr else x = x.to_s end}
      else
        raise "Ungültige Option #{keep} an Argumentposition 3 in #{p params}, muss 1 oder nil sein"
      end
    else
      self.map{|x| if x >= bottom and x <= top then x = x.chr end}.compact
    end
  end
end

Probieren wir unsere Klassenmethode mit verschiedenen Parametern aus:

array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126, 1]) # Konvertiere alle ASCII-Werte von 32-126 in ihren Zeichenwert, ansonsten behalte sie gleich (Dafür ist das optionale 1 gedacht)

Ausgabe: ["1", "2", "a", "b", "c"]

Okay, cool, das funktioniert wie geplant. Jetzt schauen wir mal, was passiert, wenn wir den dritten Parameter (1) im Array nicht übergeben.

array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126]) # Konvertiere alle ASCII-Werte von 32-126 in ihren Zeichenwert, ansonsten entferne sie (1 ist keine Parameteroption)

Ausgabe: ["a", "b", "c"]

Wie Sie sehen können, wurde die dritte Option im Array entfernt, was einen anderen Abschnitt in der Methode initiiert und alle ASCII-Werte entfernt, die nicht in unserem Bereich liegen (32-126)

Alternativ hätten wir den Wert als nil in den Parametern angegeben können. Das würde ähnlich aussehen wie der folgende Code-Block:

def ascii_to_text(top, bottom, keep = nil)
  if keep.nil?
    self.map{|x| if x >= bottom and x <= top then x = x.chr end}.compact
  else
    self.map{|x| if x >= bottom and x <= top then x = x.chr else x = x.to_s end}
end

-1voto

m4risU Punkte 1221

Es ist möglich :) Nur Definition ändern

def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )

zu

def ldap_get ( base_dn, filter, *param_array, attrs=nil )
scope = param_array.first || LDAP::LDAP_SCOPE_SUBTREE

scope wird jetzt im Array an erster Stelle sein. Wenn Sie 3 Argumente angeben, werden base_dn, filter und attrs zugewiesen und param_array wird [] sein Bei 4 oder mehr Argumenten wird param_array [Argument1, oder_mehr, und_mehr] sein

Nachteil ist... es ist eine unklare Lösung, wirklich hässlich. Dies soll darauf antworten, dass es möglich ist, ein Argument in der Mitte des Funktionsaufrufs in Ruby zu ignorieren :)

Ein weiteres, was Sie tun müssen, ist den Standardwert von scope neu zu schreiben.

4 Stimmen

Diese Lösung ist komplett falsch. Es handelt sich hierbei um einen Syntaxfehler, wenn ein Standardwertparameter (attrs=nil) nach einem Splat (*param_array) verwendet wird.

3 Stimmen

-1: Erik hat recht. Verursacht einen Syntaxfehler in irb 2.0.0p247. Laut The Ruby Programming Language musste in Ruby 1.8 der Splat-Parameter bis auf ein ¶meter der letzte sein, aber in Ruby 1.9 konnte er auch von "normalen Parametern" gefolgt werden. In keinem Fall war ein Parameter mit einem Standardwert nach einem Parameter mit einem Splat erlaubt.

0 Stimmen

Die Splat-Methode ist auf Seite 186/187 des Ruby-Programmierhandbuchs in Ordnung zu verwenden. Es muss der letzte Parameter in der Methode sein, es sei denn, das kaufmännische Und-Zeichen (&) wird verwendet.

-1voto

EriF89 Punkte 718

Sie könnten dies mit partieller Anwendung machen, obwohl die Verwendung benannter Variablen definitiv zu lesbarerem Code führt. John Resig schrieb 2008 einen Blog-Artikel darüber, wie man es in JavaScript macht: http://ejohn.org/blog/partial-functions-in-javascript/

Function.prototype.partial = function(){
  var fn = this, args = Array.prototype.slice.call(arguments);
  return function(){
    var arg = 0;
    for ( var i = 0; i < args.length && arg < arguments.length; i++ )
      if ( args[i] === undefined )
        args[i] = arguments[arg++];
    return fn.apply(this, args);
  };
};

Es wäre wahrscheinlich möglich, dasselbe Prinzip in Ruby anzuwenden (außer für die prototypische Vererbung).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X