[英]Ruby: Pass super into another method to execute conditionally
I have some code that looks like this: 我有一些看起来像这样的代码:
if args
eval("super(#{args.join(',')})")
else
super
end
twice in a method. 两次。 I'd like to move it so that my code looks more like: 我想移动它,以便我的代码更像:
def special_method
if a
some_block do
call_super(args, super_method)
end
else
call_super(args, super_method)
end
end
def call_super(args, super_method)
if args
eval("super(#{args.join(',')})")
else
super
end
end
I need to have a reference to the super
I want to call (super special_method
), since if I just create a method call_super
and call super
, it calls call_super
on the superclass instead. 我需要有对基准super
我想打电话给(超级special_method
),因为如果我只是创造一个方法call_super
并调用super
,它调用call_super
在超代替。
Does any of this make sense? 这有道理吗? x_x x_x
It makes sense except for why you would ever need it. 这是有道理的,除了您为什么会需要它。 super
already passes any parameters that the current method receives. super
已经传递了当前方法接收的任何参数。 super()
passes no params. super()
传递任何参数。 super(*args)
passes any params in args
, or no params if args
is []
or nil
. super(*args)
通过在任何PARAMS args
,或不PARAMS如果args
是[]
或nil
。
If you actually want to do what your code currently does (pass args
if they are non- nil
, but current method's params if not) and not what I think you wanted, you can write args ? super(*args) : super
如果您实际上想做代码当前所做的事情(如果它们不是nil
,则传递args
如果不是,则传递当前方法的参数),而不是我想的那样,您可以编写args ? super(*args) : super
args ? super(*args) : super
as a short alternative (you can't put this in another method since it wouldn't know what the current parameters are). args ? super(*args) : super
作为简短替代(您不能将其放在另一种方法中,因为它不知道当前参数是什么)。
(Also, you will find that in 99% of cases you think eval
is the answer, there is a better answer.) (此外,您会发现在99%的情况下,您认为eval
是答案,会有更好的答案。)
EDIT in response to the comment: 编辑以回应评论:
if args
is ['testing', 1]
, then super(args)
will pass one parameter that is an array; 如果args
是['testing', 1]
,则super(args)
将传递一个参数,该参数是一个数组; super(*args)
passes two parameters (a string and an integer): super(*args)
传递两个参数(一个字符串和一个整数):
# a module
module Foo
def special_method
# multiple arguments in `args`
args = ['testing', 1]
super(*args)
end
end
class Bar
# fixed number of arguments (without splats):
def special_method(first, second)
puts "First parameter: #{first}"
puts "Second parameter: #{second}"
end
end
# subclass that includes the module
class Baz < Bar
include Foo
end
Baz.new.special_method
# First parameter: testing
# Second parameter: 1
(Note that "multiple arguments in *args
" does not make sense, as *args
is not a variable, args
is). (请注意,“ *args
多个参数”没有意义,因为*args
不是变量,而args
是变量)。
I think one of the reasons for the confusion is the fact that splat has two different but related roles. 我认为造成混乱的原因之一是splat具有两个不同但相关的角色。 In method definitions, they collect arguments into an array. 在方法定义中,它们将参数收集到数组中。 Everywhere else, they distribute an array to an argument list. 他们在其他任何地方将数组分配到参数列表。
require 'pp'
def foo(*args)
pp args
end
foo([1, 2]) # all the parameters (namely, the one) collected into `args`
# [[1, 2]]
foo(1, 2) # all the parameters (the two) collected into `args`
# [1, 2]
foo(*[1, 2]) # distribute `[1, 2]` to two parameters; collect both into `args`
# [1, 2]
def foo(args)
pp args
end
foo([1, 2]) # all the parameters (the one that exists) passed as-is
# [1, 2]
foo(1, 2) # all the parameters (the two) passed as-is, but method expects one
# ArgumentError: wrong number of arguments (2 for 1)
foo(*[1, 2]) # distribute `[1, 2]` to two parameters, but method expects one
# ArgumentError: wrong number of arguments (2 for 1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.