- 浏览: 3009380 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
在Ruby里,给可能未定义或值为nil的变量设置一个默认初始值时,惯用法是使用||=的办法,例如:
这个例子里,无论a原本有没有定义,或者定义是什么都好,都会被当作是一个变量。如果原本a是一个有非nil非false值的变量,那么a的值不变;如果a原本是一个方法,那么作为方法名的a会被作为变量名的a所屏蔽,并且a被赋值为[]。
看下面这个例子:
可以看到变量名屏蔽方法名的行为。
OK,那有什么好说的呢?Ola Bini最近做过一个关于在JVM上创造自己的语言的讲演,其中有一部分是向与会者介绍Ruby。他演示的时候提到诸如a ||= 1没问题,但他一时以为在a还没定义的时候a = a || 1不行,在演示的时候稍微卡了一下。乍一看,要是根据他当时的思路,确实会觉得这个不行。
思路是:如果单独写a || 1,在a还没定义的时候,访问a的值会得到“未定义局部变量或方法”的错误;把这个放在赋值的右手边,就应该会在能够赋值之前就先遇到错误了。
但实际上,a ||= 1就是a = a || 1的简写,这两者在运行时的行为是一样的。那为什么单独写a || 1会出问题,而放在赋值的右手边就没事了呢?
因为Ruby要想办法知道一个名字到底是变量还是方法调用。最直观的判断依据是,执行到当前位置时这个名字有没有出现在赋值符号的左手边,有的话就把这个名字当作变量,没有的话就默认把这个名字当作方法;后一种情况中如果没有这个名字的方法,那就出错了。
像这样就会出错:
而这样就不会:
也就是说不用真的执行赋值,只要Ruby解析器能看到某个名字出现在赋值符号的左边就够了,就会创建一个这个名字的变量,未赋值时值为nil。
回到a = a || 1。这里Ruby先看到了a出现在赋值符号的左手边,于是创建出变量a,值为nil;接下来对赋值符号右手边求值,nil || 1的结果是1;然后完成赋值,a的值就是1了。单独的a || 1则没这待遇,得看前面有没有别的地方让a存在,不然就会出错。
以前在好多地方都有人提到过Ruby的这个行为。昨晚跟NS老兄聊的时候突然想起||的问题一时没想通,多得他提醒才又想起来了。记下来免得以后又糊涂……
a ||= [] a << 'first'
这个例子里,无论a原本有没有定义,或者定义是什么都好,都会被当作是一个变量。如果原本a是一个有非nil非false值的变量,那么a的值不变;如果a原本是一个方法,那么作为方法名的a会被作为变量名的a所屏蔽,并且a被赋值为[]。
看下面这个例子:
a ||= 1 puts a # 1 def b 2 end puts b # 2 puts b || 3 # 2 b ||= 3 puts b # 3 puts method(:b).call # 2
可以看到变量名屏蔽方法名的行为。
OK,那有什么好说的呢?Ola Bini最近做过一个关于在JVM上创造自己的语言的讲演,其中有一部分是向与会者介绍Ruby。他演示的时候提到诸如a ||= 1没问题,但他一时以为在a还没定义的时候a = a || 1不行,在演示的时候稍微卡了一下。乍一看,要是根据他当时的思路,确实会觉得这个不行。
思路是:如果单独写a || 1,在a还没定义的时候,访问a的值会得到“未定义局部变量或方法”的错误;把这个放在赋值的右手边,就应该会在能够赋值之前就先遇到错误了。
但实际上,a ||= 1就是a = a || 1的简写,这两者在运行时的行为是一样的。那为什么单独写a || 1会出问题,而放在赋值的右手边就没事了呢?
因为Ruby要想办法知道一个名字到底是变量还是方法调用。最直观的判断依据是,执行到当前位置时这个名字有没有出现在赋值符号的左手边,有的话就把这个名字当作变量,没有的话就默认把这个名字当作方法;后一种情况中如果没有这个名字的方法,那就出错了。
像这样就会出错:
def foo puts b # undefined local variable or method `b' b = 1 if false end foo
而这样就不会:
def foo b = 1 if false puts b # nil end foo
也就是说不用真的执行赋值,只要Ruby解析器能看到某个名字出现在赋值符号的左边就够了,就会创建一个这个名字的变量,未赋值时值为nil。
回到a = a || 1。这里Ruby先看到了a出现在赋值符号的左手边,于是创建出变量a,值为nil;接下来对赋值符号右手边求值,nil || 1的结果是1;然后完成赋值,a的值就是1了。单独的a || 1则没这待遇,得看前面有没有别的地方让a存在,不然就会出错。
以前在好多地方都有人提到过Ruby的这个行为。昨晚跟NS老兄聊的时候突然想起||的问题一时没想通,多得他提醒才又想起来了。记下来免得以后又糊涂……
评论
2 楼
RednaxelaFX
2009-04-07
1 楼
night_stalker
2009-04-05
油头粉面的 Ola 被卡住的时候真尴尬……
其实这个特性有好处的:如果不小心写错了一个字母,就会弹出一个error
其实这个特性有好处的:如果不小心写错了一个字母,就会弹出一个error
def fun very_long_parameter_nameeeeeeeeeeeee very_long_parameter_nameeeeeeeeeeee || 'bastard!' end
发表评论
-
字符串的一般封装方式的内存布局 (0): 拿在手上的是什么
2013-11-04 18:22 21337(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
RubyConf notes
2011-11-08 19:10 0symmetric coroutine Fiber#trans ... -
ShanghaiOnRails第八次线下活动——你不需要知道的Ruby实现
2010-11-12 15:39 2776上个月底正好赶上参加了ShanghaiOnRails 第八次线 ... -
JRuby的运行模式
2010-11-01 11:21 0// 老的JRuby还是用org.jruby.evaluato ... -
你不需要知道的Ruby草稿
2010-10-27 11:25 0一些Ruby实现 Ruby 1.8 树遍历解释 Ruby 1 ... -
Ruby里的fiber/coroutine例子
2010-01-26 18:33 0Ruby 1.9开始支持fiber。与“fiber”一词的一般 ... -
JRuby使用技巧收集
2009-12-28 09:35 0java.lang.Thread.new { puts &qu ... -
特殊类型的eigenclass
2009-12-17 03:39 0Fixnum的实例没有eigenclass true、fals ... -
奇怪的参数
2009-12-08 02:25 0默认参数与闭包的组合 真正的问题不是只是默认参数看起来很诡异, ... -
MacRuby的执行模式
2009-12-07 07:41 0mailing-list macruby-devel http ... -
Rubinius的执行模型
2009-12-05 15:22 0Rubinius wants to help YOU make ... -
Ruby 1.8和1.9中String#hash的实现
2009-11-22 18:23 01.8 string.c int rb_str_hash(s ... -
To囧:拿你来测测Watir...
2009-11-21 22:38 3386iaimstar 写道@RednaxelaFX 你最近ruby ... -
[标题党] MagLev中GC类的真相……
2009-11-21 14:46 0注意到本文的标题:我是说“GC类”的真相,不是说GC的真相哦~ ... -
小试rubyzip的一个脚本
2009-11-17 20:42 3396呼,今天开始3天都是新人培训,总算可以抽点时间发一帖。 现在在 ... -
爬一下Google和百度看口碑对它们做的SEO效果如何
2009-11-09 00:27 0#!/usr/bin/env ruby require ... -
把Mechanize的html_parser改回到Hpricot
2009-11-08 14:45 3044记得我最初开始用Nokogir ... -
使用新的RubyInstaller
2009-11-07 02:37 0Hpricot的安装需要编译,需要devkit -
Ruby metaprogramming tech notes
2009-09-28 15:39 0class Builder def self.build ...
相关推荐
RH850/F1L是瑞萨的一款汽车级的32bit芯片/MCU,应用中经常遇到很多把某个变量定义到指定地址的要求,这份资料就是说明如何定义一个变量到指定地址的,使用的IDE是CS+。 适用于使用RH850/F1L芯片进行软件开发的...
对于Oracle学习者用处很大,是关于Oracle变量及在存储过程、触发器及函数的使用
关于function类中定义变量this的简单说明 <!DOCTYPE html> <html> <head> </head> [removed] function TObject(){ this.name1 = "aa";//这里不能写name,name是window的变量。否则无法...
#实例变量:定义在方法中的变量,只作用于当前实例的类。 例子: class Turtle:#python 中类名约定以大写字母开头 '''关于类的简单例子。。。''' #属性 == 类变量 color ="green" weight="10kg" legs=4 shell...
本文主要跟大家介绍了关于Vue定义全局变量与常量的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 我想要定义一个变量, 在项目的任何地方都可以访问到, 不需要每一次使用的时候, 都引入...
gRPC 关于c#的demo,内容包含proto文件变量以及方法接口的定义,以及接口功能的c#实现
第一,前端wxml的数据渲染是通过设置此对象中定义的变量进行关联展现的 第二,定义JS页面中的页面局部变量,使其整个页面中可使用或调用 对象data定义的变量支持各种数据类型,string,int,[],{} **第一.**wxml数据...
文件如下 VC2005
变量对于学习js,学习编程语言的同学在熟悉不过了,在这里就不在阐述官方的定义了,网上太多了,今天我们就从生活中来理解他 1.什么是变量? 比如: 一个水杯里面装了水,这个水杯就是变量; 一瓶啤酒,这个啤酒瓶...
总结如下:1.一般情况下,函数在调用子函数时,子函数必须先声明,要不会报错。(一般都将函数的声明放在一下头文件里)2.如若子函数为返回值是int时,...3.static修饰的函数作用域为从声明/定义处到源文件结尾处为止。
在cnblogs上看了关于js的一些文章 ,做下笔记: 先看代码1: function car(){ var wheel = 3;//私有变量 this.wheel = 4;//公有变量 alert(wheel); alert(this.wheel); } var car1 = new...
本文实例讲述了ES6 let和const定义变量与常量的应用。分享给大家供大家参考,具体如下: 关于 let let是小作用域的变量的声明 { var a = 12; let b = 15; { console.log(a); // 12 console.log(b); // 15 } ...
关于在keil c51中如何定位变量、常数和函数的位置
//定义一个结构体,这个结构体用来存算法中要用到的各种数据 bit g_bPIDRunFlag = 0; //PID运行标志位,PID算法不是一直在运算。而是每隔一定时间,算一次。 /* *************************************************...
主要给大家介绍了关于C/C++语言中全局变量重复定义问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
union的概念与struct和class定义的类不同, 因为union在同一时间只能存储一个数据成员。但是由union定义的类也是可以有成员函 数的。union定义的类访问权限默认为public。 94 操作符重载(Overloading operators) ...
//定义一个变量,下面赋值给$b $b = $a;//这一步没有在$a之前加符号&,像这样子”$b= & $a”。没有加&,实际上原理是会将变量$a复制拷贝一份,也就是内存中重新申请一个地址存储变量$b了 ps:在php中,使用”=”直接...
本文实例讲述了Python全局变量与局部变量区别及用法。分享给大家供大家参考,具体如下: 对于很多初学的同学,对全局和局部变量容易混淆,看看下面给大家的讲解相信都应该明白两者的区别了。 定义: 全局变量:在...
对于参数,可以先定义一个参数变量,然后取变量地址就ok了。 如果是想拦截其他进程中的api,则必须使用其他一些方法,最典型的方法是利用VirtualAllocEx函数来在其他进程中申请和提交内存空间。然后用...