Ruby 可选参数

发布于 2024-07-18 07:17:57 字数 256 浏览 10 评论 0原文

如果我像这样定义一个 Ruby 函数:

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

如何调用它只提供前 2 个和最后一个参数? 为什么类似的事情不可能

ldap_get( base_dn, filter, , X)

,或者如果可能的话,如何才能做到?

If I define a Ruby functions like this:

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

How can I call it supplying only the first 2 and the last args? Why isn't something like

ldap_get( base_dn, filter, , X)

possible or if it is possible, how can it be done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

莫相离 2024-07-25 07:17:57

使用选项哈希几乎总是更好。

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

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

You are almost always better off using an options hash.

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

ldap_get(base_dn, filter, :attrs => X)
秋意浓 2024-07-25 07:17:57

目前,这对于红宝石来说是不可能的。 您不能将“空”属性传递给方法。 最接近的方法是传递 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

现在,如果您按上述方式调用该方法,则行为将如您所期望的那样。

This isn't possible with ruby currently. You can't pass 'empty' attributes to methods. The closest you can get is to pass nil:

ldap_get(base_dn, filter, nil, X)

However, this will set the scope to nil, not LDAP::LDAP_SCOPE_SUBTREE.

What you can do is set the default value within your method:

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

Now if you call the method as above, the behaviour will be as you expect.

只等公子 2024-07-25 07:17:57

随着时间的推移,Ruby 2 版本开始支持命名参数:

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"

Time has moved on and since version 2 Ruby supports named parameters:

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"
没企图 2024-07-25 07:17:57

无法按照您定义的 ldap_get 方式执行此操作。 但是,如果您像这样定义 ldap_get:

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

现在您可以:

ldap_get( base_dn, filter, X )

但是现在您遇到了问题,您无法使用前两个参数和最后一个参数调用它(与之前相同的问题,但现在最后一个参数不同)。

这样做的理由很简单:Ruby 中的每个参数不需要有默认值,因此您不能按照您指定的方式调用它。 例如,在您的情况下,前两个参数没有默认值。

It isn't possible to do it the way you've defined ldap_get. However, if you define ldap_get like this:

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

Now you can:

ldap_get( base_dn, filter, X )

But now you have problem that you can't call it with the first two args and the last arg (the same problem as before but now the last arg is different).

The rationale for this is simple: Every argument in Ruby isn't required to have a default value, so you can't call it the way you've specified. In your case, for example, the first two arguments don't have default values.

没︽人懂的悲伤 2024-07-25 07:17:57

1)你不能重载该方法(为什么ruby不支持方法重载?)那么为什么不完全编写一个新方法呢?

2)我使用 splat 运算符 * 对于零或更多长度的数组解决了类似的问题。 然后,如果我想传递一个参数,我可以,它被解释为一个数组,但如果我想调用不带任何参数的方法,那么我不必传递任何东西。 请参阅Ruby 编程语言第 186/187 页

1) You cannot overload the method (Why doesn't ruby support method overloading?) so why not write a new method altogether?

2) I solved a similar problem using the splat operator * for an array of zero or more length. Then, if I want to pass a parameter(s) I can, it is interpreted as an array, but if I want to call the method without any parameter then I don't have to pass anything. See Ruby Programming Language pages 186/187

黯淡〆 2024-07-25 07:17:57

最近我找到了解决这个问题的方法。 我想在数组类中创建一个带有可选参数的方法,以保留或丢弃数组中的元素。

我模拟这个的方法是传递一个数组作为参数,然后检查该索引处的值是否为零。

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

Recently I found a way around this. I wanted to create a method in the array class with an optional parameter, to keep or discard elements in the array.

The way I simulated this was by passing an array as the parameter, and then checking if the value at that index was nil or not.

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

Trying out our class method with different parameters:

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"]

Okay, cool that works as planned. Now let's check and see what happens if we don't pass in the the third parameter option (1) in the 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"]

As you can see, the third option in the array has been removed, thus initiating a different section in the method and removing all ASCII values that are not in our range (32-126)

Alternatively, we could had issued the value as nil in the parameters. Which would look similar to the following 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
慵挽 2024-07-25 07:17:57

有可能的 :)
只需将定义更改

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​​ 中可以在函数调用过程中省略参数:)

您必须做的另一件事是重写作用域的默认值。

It is possible :)
Just change definition

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

to

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

scope will be now in array on its first place.
When you provide 3 arguments, then you will have assigned base_dn, filter and attrs and param_array will be []
When 4 and more arguments then param_array will be [argument1, or_more, and_more]

Downside is... it is unclear solution, really ugly. This is to answer that it is possible to ommit argument in the middle of function call in ruby :)

Another thing you have to do is to rewrite default value of scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文