Nil*_*ann 4 ruby variables scope reference
我偶然发现了一些我不太了解的事情.我知道ruby中的变量是引用.所以很棒的东西是可能的.但是当我将变量传递给方法时,它表现得很奇怪:
my_var_a = "nothing happend to me"
my_var_b = "nothing happend to me"
def parse_set(my_var_set)
my_var_set = "my value changed"
end
def parse_sub(my_var_sub)
my_var_sub.sub! /(.*)/, "my value changed"
end
parse_set(my_var_a)
parse_sub(my_var_b)
my_var_a # => "nothing happend to me"
my_var_b # => "my value changed"
Run Code Online (Sandbox Code Playgroud)
你能解释一下为什么它可以使用sub!并=保持对象不变吗?我怎样才能避免使用sub!但结果相同?
Kal*_*see 12
my_var_a并且my_var_set是不同的引用,但它们指向同一个对象.如果您修改了对象my_var_set,则更改将显示在my_var_a.但是,如果您my_var_set在新对象上重新指定,则不会改变my_var_a指向的对象.
编辑:澄清......
Ruby所做的是通过值传递引用.当你说
my_var_a = "nothing happend to me"
Run Code Online (Sandbox Code Playgroud)
Ruby在内存位置保存字符串"没有任何事情发生在我身上"(让我们称之为1000),并将my_var_a引用保存在另一个内存位置(比方说2000).当您的代码使用时my_var_a,解释器查看位置2000,看它指向1000,然后从1000获取实际的字符串值.
当你调用时parse_set(my_var_a),Ruby实际上创建了一个名为的新引用,my_var_set并将其my_var_a指向指向的字符串(内存位置1000).但是,my_var_set是my_var_a引用的副本- 假设my_var_set是在内存位置3000创建的,my_var_a并且在内存中 my_var_set是2个完全不同的引用,它们恰好指向保存字符串值的相同的精确内存位置.
语句my_var_set = "my value changed"在parse_set内存中创建一个新字符串并指向my_var_set该新内存位置.但是,这并没有改变原始my_var_a参考点!现在my_var_set指向不同的内存位置,您对该变量所做的任何操作都不会影响my_var_a.
同样的参考副本parse_sub也会发生.但parse_sub更改字符串的原因是因为您直接在my_var_sub引用上调用方法.执行此操作时,解释器将获取my_var_sub指向的对象,然后对其进行修改.因此,更改将显示在my_var_a引用中,因为它仍指向相同的字符串.
irb(main):008:0* a = 'abc'
=> "abc"
irb(main):009:0> a.replace('def')
=> "def"
irb(main):010:0> a
=> "def"
Run Code Online (Sandbox Code Playgroud)
replace在我用Ruby编程的这些年里,我不得不使用零次.我想知道你的代码是否有更好的设计.
大多数改变接收器的字符串方法都带有后缀!(sub!,大写!,chomp!等)更改接收器的一些不是后缀!(替换是一个).如果调用更改接收器的方法,则对该对象的任何和所有引用都将看到更改.如果调用不更改接收器的方法,则该方法返回一个新字符串.
gsub不会修改接收器,而是返回一个新的String实例:
a = "foo"
b = a
p a.sub(/o/, '#') # "f##"
p a # => "foo"
p b # => "foo"
Run Code Online (Sandbox Code Playgroud)
GSUB!修改接收器:
a = "foo"
b = a
p a.sub!(/o/, '#') # => "f#o"
p a # => "f#o"
p b # => "f#o"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10447 次 |
| 最近记录: |