Ruby 一个 Ruby 笔试题

simlegate · 2013年07月21日 · 最后由 dddd1919 回复于 2013年08月15日 · 4989 次阅读
x = 2 if defined? x  
if defined? x
    x = 2
end 

上面两段代码x的值

@ginchenorlee

2 nil

我是在终端运行看结果的。

我不知道。

if defined? 改成 if not defined? 才有实际意义。

a = a 。。这个没太大意义,就是吹牛用得上

这种面试题。。

#4 楼 @edgar_wang_cn 这个答案可以解释的很清楚呢 @simlegate +1

其实 erb 里容易被这个坑到,所以 Rails 里有 local_assigns

第一个问题是,如果一个变量的赋值语句出现了,虽然没有被执行,但这个变量就会被认为已经存在了,比较典型的例子是

x = 3 if false
defined? x

这段代码的结果是 x 是 local variable,虽然第一行没有被执行。

第二个问题就是最普通情况,x 没有被定义

记得初学 ruby 时看 ruby: from novice to professional 头几页也有介绍。 后来看别人的代码时,因为忘了,结果纠结半天。

这个是考查作用域的

ruby 是解释型的语言,采用的方式是压栈方式来解析的,x=3 if defined?x 这样不管执不执行,x 都已经存在栈里面了。

#13 楼 @xautjzd 但是为什么执行了 x = 3 ? x = 3 if defined? x # => 3

#14 楼 @simlegate “不管执不执行”说的不恰当,既然已经在栈里面了,那肯定就是 defined 了

2.0.0p247 :001 > code = <<END
2.0.0p247 :002"> x =2 if defined? x
2.0.0p247 :003"> END
 => "x =2 if defined? x\n"
2.0.0p247 :004 > puts RubyVM::InstructionSequence.compile(code).disasm
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] x
0000 trace            1                                               (   1)
0002 putnil
0003 putobject        "local-variable"
0005 swap
0006 pop
0007 branchunless     16
0009 putobject        2
0011 dup
0012 setlocal_OP__WC__0 2
0014 leave
0015 pop
0016 putnil
0017 leave
 => nil

#17 楼 @simlegate 在 parserx = 2 if defined? x这段代码时,第一次遇到x时它就会被定义,然后defined? x的值就是true了,所有x=2就会被执行。

果然是坑。这应该算 bug 吧。

#19 楼 @blackanger 应该不是 bug,ruby 编程语言那本书里专门说了这个问题,感觉就是这么设计的

#20 楼 @goinaction 好吧,我想也不应该是 bug,否则在 Ruby2.0 里应该被改了。以后使用的时候需要小心。

真心没注意到这些个问题,学习了

学习了。

用 rails 的 console 试试看,结果都是 2。

解释型语言

需要 登录 后方可回复, 如果你还没有账号请 注册新账号