このようなRuby関数を定義すると:
def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )
最初の2つと最後の引数のみを指定して呼び出すにはどうすればよいですか?なぜそんなものではないのですか
ldap_get( base_dn, filter, , X)
可能ですか、それが可能であれば、どのように行うことができますか?
このようなRuby関数を定義すると:
def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )
最初の2つと最後の引数のみを指定して呼び出すにはどうすればよいですか?なぜそんなものではないのですか
ldap_get( base_dn, filter, , X)
可能ですか、それが可能であれば、どのように行うことができますか?
回答:
これはルビーでは現在不可能です。「空」の属性をメソッドに渡すことはできません。あなたが得ることができる最も近いものはnilを渡すことです:
ldap_get(base_dn, filter, nil, X)
ただし、これによりスコープがnilに設定され、LDAP :: LDAP_SCOPE_SUBTREEではありません。
あなたができることはあなたのメソッド内でデフォルト値を設定することです:
def ldap_get(base_dn, filter, scope = nil, attrs = nil)
scope ||= LDAP::LDAP_SCOPE_SUBTREE
... do something ...
end
上記のようにメソッドを呼び出すと、期待どおりの動作になります。
xyz||=true
。それがnilなら、それは常に本当だと言っています。それが本当なら、それは本当です。
scope ||= true
ているので、これを行うためのより良い方法がであると誰も言っていないことに驚いていscope = LDAP::LDAP_SCOPE_SUBTREE if scope.nil?
ます。もちろん、それnil
は無効な値であると想定しています。
nil
。いくつかは表記を好むことがあります。ldap_get(base_dn, filter, _, X)
(注:私は知りません(まだ)これはRubyで導入された際に興味深い。SOスレッドを)。
ほとんどの場合、オプションハッシュを使用する方がベターです。
def ldap_get(base_dn, filter, options = {})
options[:scope] ||= LDAP::LDAP_SCOPE_SUBTREE
...
end
ldap_get(base_dn, filter, :attrs => X)
options = default_options.merge(options)
時間は進んでおり、バージョン2以降、Rubyは名前付きパラメーターをサポートしています。
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"
定義した方法で行うことはできませんldap_get
。ただし、次のように定義した場合ldap_get
:
def ldap_get ( base_dn, filter, attrs=nil, scope=LDAP::LDAP_SCOPE_SUBTREE )
今することができます:
ldap_get( base_dn, filter, X )
しかし、今、最初の2つの引数と最後の引数を使用してそれを呼び出すことができないという問題があります(以前と同じ問題ですが、最後の引数が異なります)。
この理由は単純です。Rubyのすべての引数にデフォルト値を設定する必要はないため、指定した方法で呼び出すことはできません。たとえば、最初の2つの引数にデフォルト値がない場合などです。
1)メソッドをオーバーロードすることはできません(Rubyがメソッドのオーバーロードをサポートしないのはなぜですか?)それで、新しいメソッドを完全に記述しないのはなぜですか?
2)長さが0以上の配列に対して、splat演算子*を使用して同様の問題を解決しました。次に、できる限りパラメーターを渡したい場合は、配列として解釈されますが、パラメーターなしでメソッドを呼び出したい場合は、何も渡す必要はありません。Rubyプログラミング言語のページ186/187を参照してください
最近、これを回避する方法を見つけました。配列内の要素を保持または破棄するために、オプションのパラメーターを使用して配列クラスにメソッドを作成したかったのです。
これをシミュレートする方法は、パラメーターとして配列を渡し、そのインデックスの値がnilかどうかをチェックすることでした。
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
さまざまなパラメーターを使用してクラスメソッドを試してみます。
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)
出力: ["1", "2", "a", "b", "c"]
かしこまりました。計画どおりに機能します。次に、配列の3番目のパラメーターオプション(1)を渡さない場合に何が起こるかを確認してみましょう。
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)
出力: ["a", "b", "c"]
ご覧のとおり、配列の3番目のオプションが削除されているため、メソッドの別のセクションが開始され、範囲(32〜126)にないすべてのASCII値が削除されます。
あるいは、パラメーターで値をnilとして発行することもできます。次のコードブロックのようになります。
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
可能です:)定義を変更するだけです
def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )
に
def ldap_get ( base_dn, filter, *param_array, attrs=nil )
scope = param_array.first || LDAP::LDAP_SCOPE_SUBTREE
スコープは最初は配列になりました。3つの引数を指定すると、base_dn、filter、attrsが割り当てられ、param_arrayは[]になります。4つ以上の引数を指定すると、param_arrayは[argument1、or_more、and_more]になります
欠点は...それは不明確な解決策であり、本当に醜いです。これは、ルビの関数呼び出しの途中で引数を省略できることを示しています:)
あなたがしなければならないもう一つは、スコープのデフォルト値を書き換えることです。
attrs=nil
スプラット(*param_array
)の後にデフォルト値パラメーター()を使用するのは構文エラーです。
¶meter
が、Ruby 1.9では「通常のパラメータ」が後に続く可能性があります。どちらの場合も、スプラットのあるパラメータの後に、デフォルトが有効なパラメータはありませんでした。
名前付き変数を使用すると、コードが読みやすくなりますが、部分的なアプリケーションでこれを行うことができます。John Resigが2008年に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);
};
};
Rubyで同じ原則を適用することはおそらく可能です(プロトタイプの継承を除く)。
scope
true のデフォルト値を作成しようとしていて、を渡したfalse
場合、機能しscope ||= true
ません。と同じように評価されnil
、次のように設定されますtrue