在ruby中一切都是对象,而你向方法中传递的实质上是对象的引用( object-reference)。ruby中变量都是对象的引用。

先来看

def pref2(agr)
agr.downcase
end a2 = 'PREF2'
pref2(a2)
puts "#{a2}" #输出 PREF2

为什么调用了pref2后 a2还是大写的“PREF2”,看一下downcase的源码就不难发现问题了。

链接:https://ruby-doc.org/core-2.4.1/String.html,搜索downcase

看到str=rb_str_dup(str); 这句其实真相大白了,实际上dwoncase返回的是一个新的字符串,并不是你原来传进去的字符串对象的引用了。
所以经过了pref2方法后,a2的值并没有发生改变。

再来看

def pref1(agr)
agr.downcase!
end a1 = 'HELLO'
pref1(a1)
puts "#{a1}" #输出 hello

为什么经过了pref1方法a1的值发生了变化。还是先来看看downcase!的源码

链接:https://ruby-doc.org/core-2.4.1/String.html,搜索downcase!

查看源码后发现传入的对象引用自始至终未被更改过,所以最终返回的还是a1的引用,所以a1对象的内容在dwoncase!方法中被改变了。
 
接下来继续看看
def pref3(a,b)
a,b = b,a
end a,b = 1,2
pref3(a,b)
puts a,b #输出 1,2

为什么明明在pref3中交换了a,b结果为什么没变呢?这个问题确实比较难懂。我们可以把你的例子转换为一个更好理解的例子

变为

def pref3(a)
a = 5
end a =1
pref3(a)
puts a #输出 1

明明把a传进去了,并给它赋值为5,为什么还是1呢?我们很自然的可以想到是不是外面的a和方法中的a不是同一个东西。为了验证,我们进一步改造我们的方法

改造

def pref3(a)
a = 5
a.object_id
end a =1
a.object_id #输出3 pref3(a) #输出11
puts a

我们发现两个a的object_id不同,他们不是一个对象,而是两个。

现在我们明白了问题的关键,方法中的本地变量a指向了对象5,而外部的a仍旧指向的是对象1.

 至此整个过程我们可以理解为:

  1. 有一个对象1,我们用a保存了他的引用。
  2. 然后我们将它的“引用的拷贝”传递给了方法pref3中的本地变量a,这时本地变量a保存了1对象的引用。
  3. 我们在pref3方法中创建了5对象,将其引用赋值给了本地变量a,这时a擦去了保存的1对象的引用,而改为保存5对象的引用
  4. 调用完pref3方法 ,其本地变量a随之消亡,对象5因为没有引用而随后被垃圾回收。
  5.  而外部的变量a自始至终保存着对象1的引用。

现在回头想想你的方法中传进去的a,b虽然交换了位置,但是对外部定义的a,b没有丝毫影响。因为他们根本保存的就是不同的对象的引用。

ruby传递的是 引用的拷贝 并不是引用的本身。(其实就可以理解为值传递)
但对于基本类型是直接传递对象本身的。举个例子:
可以参考这个http://www.ruby-doc.org/core-1.9/classes/Fixnum.html
写道

“Fixnum objects have immediate value. This means that when they are assigned or passed as parameters, the actual object is passed, rather than a reference to that object. Assignment does not alias Fixnum objects. There is effectively only one Fixnum object instance for any given integer value, so, for example, you cannot add a singleton method to a Fixnum.“.

我觉得这篇文章能够结束这个话题了:http://www.khelll.com/blog/ruby/c-passes-by-reference-java-and-ruby-dont/
更有趣的讨论过程:http://www.khelll.com/blog/ruby/ruby-pass-by-value-or-by-reference/
 
 
收集整理自:http://www.iteye.com/topic/1117575 作者:洛克刘大神  万分感谢~~

总结:Ruby里是值传递还是引用传递的更多相关文章

  1. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  2. java中值传递和引用传递

    最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  3. Java中的值传递和引用传递

    这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...

  4. JavaScript 函数参数传递到底是值传递还是引用传递

    tips:这篇文章是听了四脚猫的js课程后查的,深入的理解可以参看两篇博客: JavaScript数据类型--值类型和引用类型 JavaScript数据操作--原始值和引用值的操作本质 在传统的观念里 ...

  5. java中方法的参数传递机制(值传递还是引用传递)

    看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参 ...

  6. java参数传递时到底是值传递还是引用传递

    java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...

  7. Java面向对象-方法的值传递和引用传递

    Java面向对象-方法的值传递和引用传递 0 发布时间:『 2016-08-21 14:21』  博客类别:Java核心基础  阅读(197) 评论(0) Java面向对象-方法的值传递和引用传递 方 ...

  8. String是值传递还是引用传递

    String是值传递还是引用传递 今天上班时,同事发现了一个比较有意思的问题.他把一个String类型的参数传入方法,并在方法内改变了引用的值. 然后他在方法外使用这个值,发现这个String还是之前 ...

  9. 堆栈详解 + 彻底理解Java的值传递和引用传递

    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...

  10. JAVA不可变类与可变类、值传递与引用传递深入理解

    一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: P ...

随机推荐

  1. Scrapy Item用法示例(保存item到MySQL数据库,MongoDB数据库,使用官方组件下载图片)

    需要学习的地方: 保存item到MySQL数据库,MongoDB数据库,下载图片 1.爬虫文件images.py # -*- coding: utf-8 -*- from scrapy import ...

  2. 关于 BaseHTTPServer 的介绍

    简介: (1) 基础的web服务器是一个模板,其其角色是客户端和服务器端完成必要的HTTP交互,在basehttpserver模块中可以找到一个名字叫HTTPServer 的服务器基本类 (2)处理程 ...

  3. HTML学习笔记之标签基础

    目录 1.基本标签 2.链接 3.图像 4.表格 5.列表 6.块与布局 1.基本标签 (1)标题与段落 标签 <h1> ~ <h6> 分别用于定义一至六级标题,标签 < ...

  4. python爬虫12 | 爸爸,他使坏,用动态的 Json 数据,我要怎么搞?

    在前面我们玩了好多静态的 HTML 想必你应该知道怎么去爬这些数据了 但还有一些常见的动态数据 比如 商品的评论数据 实时的直播弹幕 岛国动作片的评分 等等 这些数据是会经常发生改变的 很多网站就会用 ...

  5. hdu 5174 Ferries Wheel

    摩天轮是一个环,周围围绕着一些缆车.每个缆车按顺序编号为1,2,3...K-1,K1,2,3...K−1,K而且每个缆车也拥有一个唯一的值且保证A[i-1] < A[i] < A[i+1] ...

  6. Python之路【第一篇】:Python基础1

    本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...

  7. NTP-网络时间协议

    前言 搭建了一个linux虚拟机,发现跑着跑着时间有差异,查资料发现这个是正常的,因为系统时间和硬件时间是本地时间,会因各种原因导致跟标准时间UTC时间有差异,所以计算机界的牛人发明了NTP协议,专门 ...

  8. 题目3 : Spring Outing 微软2016校园招聘在线笔试第二场

    题目3 : Spring Outing 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 You class are planning for a spring outin ...

  9. HDU 2767-Proving Equivalences(强联通+缩点)

    题目地址:pid=2767">HDU 2767 题意:给一张有向图.求最少加几条边使这个图强连通. 思路:先求这张图的强连通分量.假设为1.则输出0(证明该图不须要加边已经是强连通的了 ...

  10. [Jest] Write data driven tests in Jest with test.each

    Often, we end up creating multiple unit tests for the same unit of code to make sure it behaves as e ...