Domanda

Se definisco un Ruby funziona in questo modo:

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

Come posso chiamarlo fornendo solo il primo 2 e l'ultimo argomento? Perché non è qualcosa di simile

ldap_get( base_dn, filter, , X)

possibile o se è possibile, come può essere fatto?

È stato utile?

Soluzione

Questo non è attualmente possibile con ruby. Non è possibile passare attributi "vuoti" ai metodi. Il più vicino che puoi ottenere è passare zero:

ldap_get(base_dn, filter, nil, X)

Tuttavia, questo imposterà l'ambito su zero, non su LDAP :: LDAP_SCOPE_SUBTREE.

Quello che puoi fare è impostare il valore predefinito nel tuo metodo:

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

Ora se chiami il metodo come sopra, il comportamento sarà come previsto.

Altri suggerimenti

Stai quasi sempre meglio usando un hash delle opzioni.

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

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

Il tempo è passato e dalla versione 2 Ruby supporta i parametri denominati:

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"

Non è possibile farlo nel modo in cui hai definito ldap_get . Tuttavia, se si definisce ldap_get in questo modo:

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

Ora puoi:

ldap_get( base_dn, filter, X )

Ma ora hai un problema che non puoi chiamarlo con i primi due argomenti e l'ultimo argomento (lo stesso problema di prima ma ora l'ultimo argomento è diverso).

La logica di ciò è semplice: ogni argomento in Ruby non deve avere un valore predefinito, quindi non puoi chiamarlo come hai specificato. Nel tuo caso, ad esempio, i primi due argomenti non hanno valori predefiniti.

1) Non puoi sovraccaricare il metodo ( Why doesn ' t ruby ??supporting overloading del metodo? ), quindi perché non scrivere del tutto un nuovo metodo?

2) Ho risolto un problema simile usando l'operatore splat * per un array di zero o più lunghezze. Quindi, se voglio passare un parametro (i) che posso, viene interpretato come un array, ma se voglio chiamare il metodo senza alcun parametro, non devo passare nulla. Vedi Linguaggio di programmazione Ruby pagine 186/187

Di recente ho trovato un modo per aggirare questo. Volevo creare un metodo nella classe array con un parametro opzionale, per mantenere o scartare elementi nell'array.

Il modo in cui l'ho simulato è stato passando un array come parametro e quindi verificando se il valore di quell'indice fosse nullo o meno.

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

Prova il nostro metodo di classe con parametri diversi:

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)

output: [" 1 " ;, " 2 " ;, " a " ;, " b " ;, " c "]

Ok, bello che funziona come previsto. Ora controlliamo e vediamo cosa succede se non passiamo alla terza opzione di parametro (1) nell'array.

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)

output: [" a " ;, " b " ;, " c "]

Come puoi vedere, la terza opzione nell'array è stata rimossa, iniziando così una sezione diversa nel metodo e rimuovendo tutti i valori ASCII che non sono nel nostro intervallo (32-126)

In alternativa, avremmo potuto emettere il valore come zero nei parametri. Che sarebbe simile al seguente blocco di codice:

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

È possibile :) Cambia definizione

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

a

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

sarà ora nella matrice al primo posto. Quando fornisci 3 argomenti, allora avrai assegnato base_dn, filter e attrs e param_array sarà [] Quando 4 e più argomenti allora param_array sarà [argomento1, or_more e_more]

L'aspetto negativo è ... è una soluzione poco chiara, davvero brutta. Questo per rispondere che è possibile omettere l'argomento nel mezzo della chiamata di funzione in ruby ??:)

Un'altra cosa che devi fare è riscrivere il valore predefinito dell'ambito.

Puoi farlo con un'applicazione parziale, anche se l'uso di variabili nominate porta sicuramente a codice più leggibile. John Resig ha scritto un articolo di blog nel 2008 su come farlo in JavaScript: 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);
  };
};

Probabilmente sarebbe possibile applicare lo stesso principio in Ruby (ad eccezione dell'eredità prototipale).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top