Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby变量定义_Ruby On Rails_Ruby_Abstract Syntax Tree_Interpreted Language - Fatal编程技术网

Ruby on rails Ruby变量定义

Ruby on rails Ruby变量定义,ruby-on-rails,ruby,abstract-syntax-tree,interpreted-language,Ruby On Rails,Ruby,Abstract Syntax Tree,Interpreted Language,我在ruby中偶然发现了一个关于变量定义的奇怪行为(并在途中丢失了一盒甜甜圈): 在编译语言中,这甚至不会编译 这是否意味着ruby保留了对该变量的引用,即使它没有通过该代码段 如果是,变量定义的ifs/else考虑的深度有多深 我真不敢相信这是ruby中的预期行为。而且它不是特定于irb的,在ruby/rails代码块中运行它会得到相同的结果。我可能在这方面错了,但是ruby为变量定义了作用域。 您拥有全局范围,即$ 然后您就有了运行脚本的本地范围,这就是您在问题中演示的范围。您可以在方法

我在ruby中偶然发现了一个关于变量定义的奇怪行为(并在途中丢失了一盒甜甜圈):

在编译语言中,这甚至不会编译

  • 这是否意味着ruby保留了对该变量的引用,即使它没有通过该代码段
  • 如果是,变量定义的ifs/else考虑的深度有多深

我真不敢相信这是ruby中的预期行为。而且它不是特定于irb的,在ruby/rails代码块中运行它会得到相同的结果。

我可能在这方面错了,但是ruby为变量定义了作用域。 您拥有全局范围,即$

然后您就有了运行脚本的本地范围,这就是您在问题中演示的范围。您可以在方法内定义变量,但在运行脚本的本地范围内它仍然可用

资料来源:

这里说明了局部变量没有初始值nil,但是一旦定义,不管定义了什么,都会取它们的值

2.1.5 :001 > p 1
1
 => 1 
2.1.5 :002 > p a
NameError: undefined local variable or method `a' for main:Object
    from (irb):2
    from /Users/deh0002a/.rvm/rubies/ruby-2.1.5/bin/irb:11:in `<main>'
2.1.5 :003 > if false
2.1.5 :004?>   a = 2
2.1.5 :005?>   else
2.1.5 :006 >     a = 3
2.1.5 :007?>   end
 => 3 
2.1.5 :008 > p a
3
 => 3 
2.1.5 :009 > p$a
nil
 => nil 
2.1.5 :010 > p @a
nil
 => nil 
2.1.5 :011 > 
2.1.5:001>p1
1.
=> 1 
2.1.5:002>PA
NameError:未定义的局部变量或main:Object的方法“a”
来自(irb):2
from/Users/deh0002a/.rvm/rubies/ruby-2.1.5/bin/irb:11:in`'
2.1.5:003>如果为假
2.1.5:004?>a=2
2.1.5:005?>其他
2.1.5:006>a=3
2.1.5:007?>结束
=> 3 
2.1.5:008>PA
3.
=> 3 
2.1.5:009>p$a
无
=>零
2.1.5:010>p@a
无
=>零
2.1.5 :011 > 

区别在于全局变量和实例变量。即使没有定义它们,它们也会自动接受nil的值。

在Ruby中,引用局部变量和发送给隐式接收器的消息(没有参数列表)之间存在歧义。这意味着

foo
可以表示“取消引用局部变量”或“不带参数将消息
foo
发送到
self
”,即,它可以等效于

binding.local_variable_get(:foo)

这种歧义在解析时得到解决。当解析器遇到对
foo
的赋值时,从那时起,它将把
foo
视为局部变量,而不管赋值是否实际执行。(这毕竟是解析器无法静态确定的。只需考虑
如果rand>0.5,那么foo=42 end

在编译语言中,这甚至不会编译

没有编译语言这样的东西。编译和解释是编译器或解释器(duh!)的特性,而不是语言。语言既不编译也不解释。他们就是这样

每种语言都可以用编译器实现,每种语言都可以用解释器实现。大多数语言都有编译和解释实现(例如,C有GCC和Clang,它们是编译器,Cint和Cling,它们是解释器,Haskell有GHC,它们是编译器,Hugs,它们是解释器)

许多现代语言实现都在相同的实现中,或者在不同的阶段(例如,YARV和MRuby将Ruby源代码编译为内部字节码,然后解释该字节码),或者在混合模式引擎中(例如,HotSpot JVM同时解释和编译JVM字节码,这取决于哪个更有意义),或者两者兼而有之(例如,Rubinius在第一阶段将Ruby源代码编译成Rubinius字节码,然后两者都将该字节码编译成本机代码并进行解释,这取决于什么更有意义)

事实上,所有现有的Ruby实现都是编译的:YARV和MRuby编译成它们自己的内部字节码格式,Rubinius、MacRuby、MagLev和Topaz编译成它们自己的内部字节码格式,然后编译成本机代码,JRuby编译成JVM字节码(JVM可能会进一步编译,也可能不会进一步编译),IronRuby编译成CIL字节码(VES可能会进一步编译,也可能不会进一步编译)


Ruby这样做是因为语言规范这么说,而不是因为Ruby是“解释的”,因为事实上并非如此。Ruby唯一的纯解释实现是MRI和JRuby的早期版本,它们早就退役了。

这是因为Ruby在解析时设置局部变量作用域。
a
在这个作用域中用作局部变量,所以Ruby将其视为局部变量(尽管它从未初始化)。@MarekLipka很有趣。我感觉到它可能与解析相关,这就是为什么我在这个问题上使用AST标记的原因。从编译参数的Good call中读取它,编程语言只是一个我可能永远不会忘记的短语。我不能因此而获得荣誉,我在采访中听到过,我相信是的。
foo
binding.local_variable_get(:foo)
self.foo()
# or
public_send(:foo)