`
RednaxelaFX
  • 浏览: 3048199 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

MRI 1.8.6的irb里一个小诡异的地方(以为是IronRuby rev183的bug)

    博客分类:
  • Ruby
阅读更多
元旦前后有好长时间DLR相关的项目都没更新过source drop了。直到这两天IronRuby才从rev181更新到rev183(rubyforge上的SVN仓库的版本号)。
这个revision给了我一个小小的惊喜:ir.exe(IronRuby的console)终于在交互模式支持在全局作用域里用局部变量了。之前拿IronRuby的交互式解释器来玩的时候,方法外的变量全得用$符号修饰成全局变量,总觉得别扭。现在总算好了~指望着什么时候能在IronRuby上直接用irb...

不过今天玩的时候因为手误却发现了一个奇怪的现象。在交互式解释器里玩,写了插入运算符("<<")之后忘了写空格就写了后面的数字,然后按了回车。

先用Ruby 1.8.6 p287来实验:
E:\ironruby\build\debug>irb
irb(main):001:0> a, b = [], 'xyz'
=> []
irb(main):002:0> a <<2 <<3
irb(main):003:0" puts b.succ
irb(main):004:0" 2
xza
=> 2
irb(main):005:0> a
=> [2, 3]

Ruby 1.8.6的irb貌似是把<<2看成heredoc的起始标志了,但是行为却又不像heredoc返回字符串,而是执行了<<2到2之间的代码。不仅如此,<<2和<<3还把2和3插入到a里去了……
拜托有知道这是什么现象的人解释一下……我给弄糊涂了。
顺带一提JRuby 1.1.5的jirb的行为跟Ruby 1.8.6的irb是一样的。

然后用IronRuby rev183来测试这个现象:
E:\ironruby\build\debug>ir
IronRuby 1.0.0.0 on .NET 2.0.50727.3053
Copyright (c) Microsoft Corporation. All rights reserved.

>>> a = []
=> []
>>> a <<2 <<3
=> [2, 3]

可以看到IronRuby的ir.exe认为这就是普通的连续两个插入操作。怪哉怪哉……
(然而测试了一番之后,这个行为就Ruby语言来说却是对的。只是交互式解释器ir.exe与MRI的irb的行为不同而已。看下面)

然后回头来用JRuby看看它是如何理解这样的代码的。打开JRuby 1.1.5的jirb:
irb(main):001:0> src = <<SRCEND
irb(main):002:0" a = []
irb(main):003:0" b = 'xyz'
irb(main):004:0" a <<2 <<3
irb(main):005:0" puts b.succ
irb(main):006:0" 2
irb(main):007:0" a
irb(main):008:0" SRCEND
=> "a = []\nb = 'xyz'\na <<2 <<3\nputs b.succ\n2\na\n"
irb(main):009:0> ast = JRuby.parse src
=> RootNode
  BlockNode
    NewlineNode
      LocalAsgnNode |a| &0 >0
        ZArrayNode
    NewlineNode
      LocalAsgnNode |b| &1 >0
        StrNode =="xyz"
    NewlineNode
      CallOneArgNode |<<|
        CallOneArgNode |<<|
          LocalVarNode |a| &0 >0
          ArrayNode
            FixnumNode ==2
        ArrayNode
          FixnumNode ==3
    NewlineNode
      FCallOneArgNode |puts|
        ArrayNode
          CallNoArgNode |succ|
            LocalVarNode |b| &1 >0
    NewlineNode
      FixnumNode ==2
    NewlineNode
      LocalVarNode |a| &0 >0

可以发现JRuby认为这段代码里没有heredoc,都是普通的语句而已。也就是说跟<<后带有空格时的结果是一样的:
irb(main):001:0> src = <<SRCEND
irb(main):002:0" a = []
irb(main):003:0" b = 'xyz'
irb(main):004:0" a << 2 << 3
irb(main):005:0" puts b.succ
irb(main):006:0" 2
irb(main):007:0" a
irb(main):008:0" SRCEND
=> "a = []\nb = 'xyz'\na << 2 << 3\nputs b.succ\n2\na\n"
irb(main):009:0> ast = JRuby.parse src
=> RootNode
  BlockNode
    NewlineNode
      LocalAsgnNode |a| &0 >0
        ZArrayNode
    NewlineNode
      LocalAsgnNode |b| &1 >0
        StrNode =="xyz"
    NewlineNode
      CallOneArgNode |<<|
        CallOneArgNode |<<|
          LocalVarNode |a| &0 >0
          ArrayNode
            FixnumNode ==2
        ArrayNode
          FixnumNode ==3
    NewlineNode
      FCallOneArgNode |puts|
        ArrayNode
          CallNoArgNode |succ|
            LocalVarNode |b| &1 >0
    NewlineNode
      FixnumNode ==2
    NewlineNode
      LocalVarNode |a| &0 >0


但这是以a是数组为前提条件的。如果a不是数组呢?看看JRuby 1.1.5对这个的反应:
irb(main):001:0> JRuby.parse "a <<2 <<3\nputs 'ok'\n2"
=> RootNode
  NewlineNode
    FCallOneArgNode |a|
      ArrayNode
        CallOneArgNode |<<|
          StrNode =="puts 'ok'\n"
          ArrayNode
            FixnumNode ==3

太可爱了,等于它认为a是一个方法,那么
a <<2 <<3
puts 'ok'
2

就等价于
a("puts 'ok'" << 3)


再用Ruby 1.8.6 p287来看看:
E:\>irb
irb(main):001:0> def a(str)
irb(main):002:1>   str
irb(main):003:1> end
=> nil
irb(main):004:0> a <<2 <<3
irb(main):005:0" puts 'ok'
irb(main):006:0" 2
=> "puts 'ok'\n\003"

看,果然是把数字3给插到字符串"puts 'ok'"里了……

然而这个状况在IronRuby rev183里也是一样的:
E:\ironruby\build\debug>ir
IronRuby 1.0.0.0 on .NET 2.0.50727.3053
Copyright (c) Microsoft Corporation. All rights reserved.

>>> def a(str)
...   str
... end
=> nil
>>> a <<2 <<3
... puts 'ok'
... 2
=> "puts 'ok'\n\003"


嗯整体看来,开头碰到似乎是irb的bug。IronRuby就“忠于Ruby语言”来说做得已经越来越好了,这里应该不算IronRuby的错。
但是一不小心在代码里弄出heredoc真是够囧的。以后我无论如何都得注意在运算符两边加空格……

==========================================================================

说到IronRuby rev183,这次放到SVN的代码他们是没build测试过吧……用VS2008直接打开是build不了的。要在Microsoft.Scripting.csproj把SpecSharp相关的内容都删除掉,并将Microsoft.Scripting.Extensionattribute.csproj里一个版本号不对的System.dll的引用删掉,然后把各个project里的Reference重新设一边才能build得了。虽然不是第一次碰到这种状况了,多少还是会觉得不爽的……||||
分享到:
评论

相关推荐

    jquery-easyui-1.8.6 最后一个支持IE7的最新版本

    1.8.6版本是jQuery EasyUI系列中最后一个兼容Internet Explorer 7(IE7)的版本,对于那些仍需支持老旧浏览器的开发者来说,这是一个重要的里程碑。 【描述】中提到,这个版本使用的jQuery库是1.x系列,而后续的...

    小狐狸ChatGPT付费创作系统1.8.6独立开源版

    【标题】"小狐狸ChatGPT付费创作系统1.8.6独立开源版"是一款专为内容创作者设计的软件,它结合了先进的自然语言处理技术,如ChatGPT,为用户提供了一个付费创作平台。该系统允许创作者通过智能对话功能与用户进行...

    Unlocker-v1.8.6

    在日常使用电脑时,我们可能会遇到这样的情况:一个文件被某个进程占用,比如正在运行的程序、后台服务或者系统进程,导致我们无法对其进行常规操作。此时,Unlocker便能派上用场。 Unlocker通过深度扫描和分析,...

    vmd-1.8.6.opengl

    版本号"vmd-1.8.6.opengl"表明这是该软件的一个特定发行版,支持OpenGL图形库,这使得它能够在Linux操作系统上高效地渲染和展示复杂的分子结构。 在描述中提到"vmd-1.8.6 用于linux系统的可视化软件",这意味着这个...

    STM32CubeF1V1.8.6

    STM32CubeF1V1.8.6

    ruby-1.8.6.tar.gz 编译器

    对于.NET,虽然两者原生不兼容,但可以通过IronRuby这样的项目,提供一个在.NET Framework上的Ruby实现。 在Ruby的世界里,Rails是最知名的Web开发框架,它简化了MVC(模型-视图-控制器)架构的应用开发。即使是在...

    Unlocker v1.8.6免安装绿色正式版

    Unlocker的工作原理是通过扫描并识别出哪些进程正在使用目标文件,然后提供一个界面让用户选择是结束这些进程还是解锁文件,从而突破系统的权限限制。这一功能对于清理系统垃圾、卸载顽固软件或处理系统文件时尤为...

    Sentinel-1.8.6-Nacos作为持久化数据源

    Sentinel 是一个强大的流量控制、熔断降级和系统保护的开源框架,广泛应用于微服务架构中。在 Sentinel-1.8.6 版本中,Nacos 被引入作为持久化数据源,这使得 Sentinel 的配置和规则管理变得更加灵活和高效。Nacos ...

    quartz quartz-1.8.6 dbTables 建表sql

    版本1.8.6是Quartz的一个稳定版本,它包含了对数据库存储作业和触发器的支持。 在Quartz中,为了将任务和触发器的调度信息存储到数据库中,需要预先创建相应的数据库表。"dbTables" 文件正是为此目的提供的。这个...

    quartz-1.8.6

    Quartz是Java平台上的一个开源任务调度框架,用于在应用程序中安排和执行作业。它的版本1.8.6是我们要讨论的重点。这个版本发布于2009年,虽然现在已经有更新的版本,但1.8.6仍然是许多项目中稳定使用的版本。在这里...

    ruby-enterprise-1.8.6-20090201

    Ruby Enterprise Edition(REE)是基于Ruby 1.8.x版本的一个优化分支,主要针对服务器端应用进行了性能增强和内存管理的改进。标题“ruby-enterprise-1.8.6-20090201”揭示了这个版本的具体信息:它基于Ruby 1.8.6...

    Playmaker 1.8.6

    总结来说,Playmaker 1.8.6 是一个针对 Unity 3D 的强大可视化编程工具,特别适合美术人员使用,通过图形化界面实现游戏逻辑,减少了对编程技能的依赖。利用其状态机和动作系统,用户可以高效地创建复杂的游戏行为,...

    ruby-1.8.6.zip

    Ruby 1.8.6 是一个古老的 Ruby 语言版本,发布于2009年,是许多开发者早期学习和构建应用程序的重要版本。Ruby 是一种面向对象的、动态类型的编程语言,以其简洁、清晰的语法和强大的元编程能力而受到欢迎。在 Ruby ...

    labelimg-1.8.6 win10 exe

    Labelimg是一款在计算机视觉领域广泛应用的图像标注工具,它为用户提供了一个图形化的界面,方便地进行像素级的图像对象标注,这对于训练深度学习模型,尤其是物体检测和语义分割模型至关重要。在本文中,我们将详细...

    svn1.8.6稳定版

    首先,TortoiseSVN 1.8.6是该系列的一个重要版本,它针对64位操作系统进行了优化,确保在处理大型项目时能够提供出色性能。此版本的发布标志着TortoiseSVN在稳定性、兼容性和功能完善上的又一重大进步,为用户提供了...

    jquery-ui-1.8.6

    总结,jQuery UI 1.8.6是一个功能全面、易于使用的JavaScript UI库,它为开发者提供了一系列直观的组件和丰富的交互功能,大大简化了网页开发过程。了解并熟练掌握jQuery UI的使用,能够帮助你创建出具有专业级用户...

    ruby1.8.6(linux)

    标题与描述中的关键词“ruby1.8.6”指向了Ruby编程语言的一个特定版本,即Ruby 1.8.6。这一版本在2007年发布,是Ruby语言发展历史上的一个重要里程碑,它在性能、稳定性和安全性方面相较于之前的版本有了显著提升,...

    groovy-binary-1.8.6

    "groovy-binary-1.8.6" 是Groovy的一个特定版本,其版本号表明这是1.8系列中的第六次更新。 Groovy的特性包括: 1. **简洁的语法**:Groovy的语法比Java更为简洁,例如,它可以省略括号、分号和类型声明,使代码更...

    Keep It For Mac_v1.8.6

    文件名"Keep It For Mac_v1.8.6.dmg"表明这是一个Mac版的应用程序安装文件,用户可以通过这个DMG文件在Mac电脑上安装Keep It。通常,DMG文件是苹果操作系统特有的安装包格式,用户双击后会自动加载到Finder中,然后...

    istio-1.8.6-win.zip

    Istio是一个强大的服务网格平台,它为微服务架构提供了流量管理、安全性和可观察性等关键功能。在本文中,我们将深入探讨Istio 1.8.6版本,特别是针对Windows用户的安装和使用。 首先,让我们了解什么是服务网格。...

Global site tag (gtag.js) - Google Analytics