web-dev-qa-db-fra.com

Ruby paramètres facultatifs

Si je définis un Ruby fonctionne comme ceci:

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

Comment puis-je l'appeler en fournissant uniquement les 2 premiers et les derniers arguments? Pourquoi ce n'est pas quelque chose comme

ldap_get( base_dn, filter, , X)

possible ou si c'est possible, comment peut-on le faire?

120
Bruno Antunes

Ce n'est pas possible avec Ruby actuellement. Vous ne pouvez pas transmettre d'attributs "vides" à des méthodes. Le plus proche que vous puissiez obtenir est de transmettre nil:

ldap_get(base_dn, filter, nil, X)

Toutefois, cela définira l'étendue sur nil, pas sur LDAP :: LDAP_SCOPE_SUBTREE.

Ce que vous pouvez faire est de définir la valeur par défaut dans votre méthode:

def ldap_get(base_dn, filter, scope = nil, attrs = nil)
  scope ||= LDAP::LDAP_SCOPE_SUBTREE
  ... do something ...
end

Maintenant, si vous appelez la méthode comme ci-dessus, le comportement sera comme vous le souhaitez.

130
tomafro

Il est presque toujours préférable d’utiliser un hachage d’options.

def ldap_get(base_dn, filter, options = {})
  options[:scope] ||= LDAP::LDAP_SCOPE_SUBTREE
  ...
end

ldap_get(base_dn, filter, :attrs => X)
136
jshen

Le temps a passé et depuis la version 2 Ruby supporte les paramètres nommés:

def ldap_get ( base_dn, filter, scope: "some_scope", attrs: nil )
  p attrs
end

ldap_get("first_arg", "second_arg", attrs: "attr1, attr2") # => "attr1, attr2"
51
steenslag

Il n'est pas possible de le faire comme vous l'avez défini ldap_get. Cependant, si vous définissez ldap_get comme ça:

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

Maintenant vous pouvez:

ldap_get( base_dn, filter, X )

Mais maintenant, vous avez un problème avec le fait que vous ne pouvez pas l'appeler avec les deux premiers arguments et le dernier argument (le même problème qu'avant, mais le dernier argument est différent).

La justification de ceci est simple: chaque argument dans Ruby n'est pas obligé d'avoir une valeur par défaut, vous ne pouvez donc pas l'appeler comme vous l'avez spécifié. Dans votre cas, par exemple , les deux premiers arguments n'ont pas de valeurs par défaut.

3
Chris Bunch

1) Vous ne pouvez pas surcharger la méthode ( Pourquoi pas Ruby ne supporte pas la méthode surchargée? ) ==) alors pourquoi ne pas écrire une nouvelle méthode?

2) J'ai résolu un problème similaire en utilisant l'opérateur splat * pour un tableau de longueur égale ou supérieure à zéro. Ensuite, si je veux passer un paramètre, je le peux, il est interprété comme un tableau, mais si je veux appeler la méthode sans paramètre, je ne dois rien transmettre. Voir Ruby Programming Language pages 186/187

1
rupweb

Récemment, j'ai trouvé un moyen de contourner cela. Je voulais créer une méthode dans la classe array avec un paramètre facultatif, pour conserver ou ignorer des éléments dans le tableau.

J'ai simulé cela en passant un tableau en tant que paramètre, puis en vérifiant si la valeur à cet index était nulle ou non.

class Array
  def ascii_to_text(params)
    param_len = params.length
    if param_len > 3 or param_len < 2 then raise "Invalid number of arguments #{param_len} for 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 "Invalid option #{keep} at argument position 3 in #{p params}, must be 1 or nil"
      end
    else
      self.map{|x| if x >= bottom and x <= top then x = x.chr end}.compact
    end
  end
end

Essayer notre méthode de classe avec différents paramètres:

array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126, 1]) # Convert all ASCII values of 32-126 to their chr value otherwise keep it the same (That's what the optional 1 is for)

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

Ok, cool ça fonctionne comme prévu. Maintenant, vérifions et voyons ce qui se passe si nous ne transmettons pas le troisième paramètre option (1) du tableau.

array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126]) # Convert all ASCII values of 32-126 to their chr value else remove it (1 isn't a parameter option)

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

Comme vous pouvez le constater, la troisième option du tableau a été supprimée, ce qui ouvre une section différente dans la méthode et supprime toutes les valeurs ASCII qui ne figurent pas dans notre plage (32-126)

Alternativement, nous pourrions avoir émis la valeur comme nulle dans les paramètres. Ce qui ressemblerait au bloc de code suivant:

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
0
Singularity