如题所术,这是个没有人再以为它是真理的真理了,谁不知道啊!可我这个不长记性的,一个坑里滚了好多次了。
def fn (arg)
arg
0 if arg < 0
end
p fn(2)
p fn(-1)
你猜结果是啥?好吧,可能就我不知道吧,还在这故弄玄虚。
nil
0
我理解的“最后一条语句”一直和 ruby 理解的“最后一条语句”不是同一个语句,思想还是有点感性,ruby 他说了:我返回的是最后一条语句,那就是最后一条,即使是 if 判断错误没有进入 if 块里,那 if 判断就是我的最后一条。🙏
每次遇到要这样写的方法,都会扑通栽进这个坑里,发现问题后我每次都是这样解决的:
def fn (arg)
return 0 if arg < 0
arg
end
当然针对这个例子三目运算符就可以,但有时其中的逻辑并不是这么简单的啊,还有其他什么妙招吗?
注:此贴目的主要有俩,1.在此立个碑,长个记性,以后不要再掉坑里了;2.破个处,我也算发过贴了,做了个爱噢贼(LZ)
逗比结束!😄
def fn (arg)
if arg < 0
0
else
arg
end
end
3 . ruby 方法的执行结果默认为最后一条语句的结果
这句并不完全正确。以等号结尾的方法是特殊情况:
def name=(a)
@a = a
a * 2
end
result = (self.name= 'hello')
result #=> 'hello'
最好是这样写
def fn (arg)
arg = 0 if arg < 0
arg
end
另外我现在项目里规定必须把返回的内容写在函数最后一行,这样增加可读性
require 'ripper'
require 'pp'
def test=(n)
2
end
code1 = "self.test=1"
code2 = "self.send(:test=, 1)"
p eval code1 # =是assign,返回值永远是用于assign的值
p eval code2 # send是方法调用,调用test=方法,返回值就是这个方法的返回值
# 两段代码解析后的语法树,详见《Ruby Under A Microscope》
pp Ripper.sexp(code1)
pp Ripper.sexp(code2)
@cicholgricenchos 补充一下我运行的结果,这下算是明白了,多谢!关于 assign 和方法调用这个我再去研究下。
1 2 [:program, [[:assign, [:field, [:var_ref, [:@kw, "self", [1, 0]]], :".", [:@ident, "test", [1, 5]]], [:@int, "1", [1, 10]]]]] [:program, [[:method_add_arg, [:call, [:var_ref, [:@kw, "self", [1, 0]]], :".", [:@ident, "send", [1, 5]]], [:arg_paren, [:args_add_block, [[:symbol_literal, [:symbol, [:@ident, "test=", [1, 11]]]], [:@int, "1", [1, 18]]], false]]]]]
Process finished with exit code 0