- 浏览: 3052948 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (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 21508(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 2851上个月底正好赶上参加了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 3448iaimstar 写道@RednaxelaFX 你最近ruby ... -
[标题党] MagLev中GC类的真相……
2009-11-21 14:46 0注意到本文的标题:我是说“GC类”的真相,不是说GC的真相哦~ ... -
小试rubyzip的一个脚本
2009-11-17 20:42 3462呼,今天开始3天都是新人培训,总算可以抽点时间发一帖。 现在在 ... -
爬一下Google和百度看口碑对它们做的SEO效果如何
2009-11-09 00:27 0#!/usr/bin/env ruby require ... -
把Mechanize的html_parser改回到Hpricot
2009-11-08 14:45 3120记得我最初开始用Nokogir ... -
使用新的RubyInstaller
2009-11-07 02:37 0Hpricot的安装需要编译,需要devkit -
Ruby metaprogramming tech notes
2009-09-28 15:39 0class Builder def self.build ...
相关推荐
#### 定义及原理 迭代法是一种常用的算法设计方法,主要用于求解方程或方程组的近似根。对于一个形式为 \(f(x) = 0\) 的方程,通过数学变换得到一个新的等价形式 \(x = g(x)\)。迭代法的核心在于通过反复计算 \(g(x)...
首先,绝对值被定义为一个数在数轴上对应点与原点之间的距离。这意味着任何数的绝对值都是非负的,因为距离不能为负。例如,4的绝对值是4,表示在数轴上4与原点的距离是4个单位;同样,-5的绝对值也是5,因为-5与...
在本章中,我们将深入探讨条件数学期望的定义、性质及其应用。 首先,条件数学期望是基于某一条件下的随机变量的数学期望。对于一个二维随机变量(,),当给定的值时,的条件数学期望[| = ]是在取特定值时,的期望...
接下来,我们将深入分析LCC源代码中关于局部变量声明的处理过程。这一部分的代码主要位于 `compound` 函数中,具体如下所示: ```c #031 // 局部变量声明处理. #032 while(kind[t] == CHAR || kind[t] == STATIC #...
文件"1.2编程基础之变量定义、赋值及转换 05 填空:类型转换2.py"和"1.2编程基础之变量定义、赋值及转换 04 填空:类型转换1.py"可能是关于不同类型之间的转换练习,比如浮点数到整数的舍入(在"1.2编程基础之变量...
例如,当 \(X\) 与 \(Z\) 独立时,可以定义 \(PMI(X;Y|Z)\) 为: \[ PMI(X;Y|Z) = I(X;Y|Z) + D(p(x|z)||p^*(x|z)) + D(p(y|z)||p^*(y|z)) \] 这里,当 \(X\) 与 \(Z\) 独立时,有 \(p(x|z) = p(x)\) 和 \(p^*(x|z...
本资源是关于n次独立重复试验和二项分布的知识点总结。内容涵盖条件概率、事件的相互独立性、独立重复试验和二项分布等方面。 条件概率 条件概率是指在事件A发生的情况下,事件B发生的概率。其定义为P(B|A)=P(AB)...
- **函数声明与定义**:在C语言中,函数必须先声明后使用。例如,`int fun(int a[M][N]) {}`是函数声明,而`int fun(int a[M][N]) {...}`是函数定义。 - **主函数main()**:程序的入口点,所有C程序都必须有一个main...
在高中数学中,特别是在随机变量及其分布的学习中,条件概率是理解二项分布和其他概率模型的关键。 标题和描述提到的是高中数学课程中关于条件概率的部分,具体到2.2.1章节,即条件概率的讲解。这部分内容通常会...
宏定义、结构体定义、函数声明以及全局变量定义放到一个head.h头文件中 函数的定义放到head.cpp中 main函数放到main.cpp中 然而却报错了,提示xxx变量在*.obj文件中已定义 问题出现的原因 为什么会出现这种...
1. 矩阵的秩(Rank)定义了矩阵列向量张成的空间的维度,即最大线性无关向量组的个数。对于行阶梯阵,秩可以通过非零行的个数来确定。 2. 方程组的解的情况与矩阵的秩和增广矩阵[A, b]的秩有关。如果R(A|b) = R(A) ...
类定义与成员变量 ```cpp class date { private: int year, month, day; public: void set(int y, int m, int d); void isleapyear(); void print(); void week(); void declare(); bool wrong(); void add...
### Java中关于变量的练习题及答案解析 #### 基础知识点概述 在Java编程语言中,变量是用来存储数据的容器。理解变量的基本概念及其使用规则是学习Java的基础之一。本篇解析将针对给定的练习题进行详细解答,并...
一种常见的解法是将变量u定义为u=xy,从而将原方程转化为关于u的微分方程。当进行这种变量代换时,\( dx = \frac{du}{y} - \frac{xdu}{y} \) 和 \( dy = \frac{du}{x} \),这样可以将原方程改写为关于u的可分离变量...
在编程领域,枚举(Enum)是一种特殊的数据类型,它允许我们定义一组相关的常量,这些常量可以作为变量的值。在这个上下文中,“Enum file”可能是指使用枚举来处理或操作文件的过程。在VC++6.0,这是一个较老的...
3. **函数定义域**:第二题和第四题涉及到函数的定义域,需要找到使函数有意义的自变量x的取值范围。 4. **不等式求解**:第四题通过解不等式`f≤ 0`和`f'<x><0`来确定集合M和N,这里涉及到二次不等式的解法。 5. ...
此外,因子分解定理在实际应用中非常有用,因为它提供了一种检验统计量充分性的简便方法,而无需直接验证定义。通过分解样本的联合分布,我们可以判断统计量是否包含关于总体参数的所有信息,这对于构建有效的统计...
条件概率定义:设事件A和B是两个随机事件,如果已知事件B发生的情况下,事件A发生的概率,则称这个概率为事件A在事件B发生的条件下的概率,记为P(A|B)。它的计算公式是P(A|B) = P(AB) / P(B),其中P(AB)表示事件A和B...
题目中证明了当xxn和yy n趋向于0时,内积(y, x)也趋向于0,表明内积函数关于两变量连续。 5. **线性算子的连续性**:线性算子T从一个赋范空间X到另一个赋范空间Y是连续的,当且仅当对于X中的所有收敛序列{x_n},T(x...
这些值表明,在已知另一个变量的情况下,关于未知变量的信息量减少了多少。 - **2.3(3)** 计算了互信息 \(I(X;Y) = 0.251 \text{ bit}\),以及三个随机变量的联合熵 \(H(XYZ) = 1.585 \text{ bit}\)。互信息表示两个...