如果我定义这样的Ruby函数:
def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )
我怎么称它只提供前2个和最后一个args?为什么不像
ldap_get( base_dn, filter, , X)
可能或者如果有可能,怎么办呢?
答案 0 :(得分:136)
使用选项哈希几乎总是更好。
def ldap_get(base_dn, filter, options = {})
options[:scope] ||= LDAP::LDAP_SCOPE_SUBTREE
...
end
ldap_get(base_dn, filter, :attrs => X)
答案 1 :(得分:130)
目前无法使用ruby。您不能将“空”属性传递给方法。你能得到的最接近的是通过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
现在,如果您按上述方式调用方法,行为将如您所愿。
答案 2 :(得分:51)
时间已经过去了,因为版本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"
答案 3 :(得分:3)
无法按照您定义ldap_get
的方式进行操作。但是,如果您像这样定义ldap_get
:
def ldap_get ( base_dn, filter, attrs=nil, scope=LDAP::LDAP_SCOPE_SUBTREE )
现在你可以:
ldap_get( base_dn, filter, X )
但现在你有问题,你不能用前两个args和最后一个arg调用它(与之前相同的问题,但现在最后一个arg是不同的)。
这个的基本原理很简单:Ruby中的每个参数都不需要具有默认值,因此您无法按照指定的方式调用它。例如,在您的情况下,前两个参数没有默认值。
答案 4 :(得分:1)
1)你不能重载方法(Why doesn't ruby support method overloading?)所以为什么不写一个新的方法呢?
2)我使用splat运算符*解决了类似的问题,对于零或更长的数组。然后,如果我想传递一个参数我可以,它被解释为一个数组,但如果我想调用没有任何参数的方法,那么我不必传递任何东西。请参阅 Ruby编程语言第186/187页
答案 5 :(得分:0)
最近我找到了解决这个问题的方法。我想在数组类中创建一个带有可选参数的方法,以保留或丢弃数组中的元素。
我模拟这个的方法是通过传递数组作为参数,然后检查该索引处的值是否为零。
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"]
好的,酷的按计划运作。现在让我们检查一下如果我们没有传入数组中的第三个参数选项(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"]
如您所见,数组中的第三个选项已被删除,从而启动方法中的不同部分并删除不在我们范围内的所有ASCII值(32-126)
或者,我们可以在参数中将值发布为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
答案 6 :(得分:-1)
有可能:) 只需更改定义
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]
下行是......解决方案尚不清楚,真的很难看。这是为了回答可以在ruby中的函数调用中间省略参数:)
您需要做的另一件事是重写范围的默认值。
答案 7 :(得分:-1)
您可以使用部分应用程序执行此操作,但使用命名变量肯定会导致更易读的代码。 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中应用相同的原则(原型继承除外)。