>> a = 5
=> 5
>> b = a
=> 5
>> b = 4
=> 4
>> a
=> 5
如何設置'b'實際上是'a',以便在該示例中,變量a也將變爲4。謝謝。紅寶石變量作爲相同的對象(指針?)
>> a = 5
=> 5
>> b = a
=> 5
>> b = 4
=> 4
>> a
=> 5
如何設置'b'實際上是'a',以便在該示例中,變量a也將變爲4。謝謝。紅寶石變量作爲相同的對象(指針?)
class Ref
def initialize val
@val = val
end
attr_accessor :val
def to_s
@val.to_s
end
end
a = Ref.new(4)
b = a
puts a #=> 4
puts b #=> 4
a.val = 5
puts a #=> 5
puts b #=> 5
當你這樣做b = a
,b
指向同一個對象a
(它們具有相同的object_id
) 。
當你做a = some_other_thing
時,a將指向另一個對象,而b
保持不變。
對於Fixnum
,nil
,true
和false
,你不能在不改變object_id
改變數值。但是,由於不使用賦值(=
),所以可以在不更改object_id
,的情況下更改其他對象(字符串,數組,哈希等)。
例子:
a = 'abcd'
b = a
puts a #=> abcd
puts b #=> abcd
a.upcase! # changing a
puts a #=> ABCD
puts b #=> ABCD
a = a.downcase # assigning a
puts a #=> abcd
puts b #=> ABCD
示例使用數組:
a = [1]
b = a
p a #=> [1]
p b #=> [1]
a << 2 # changing a
p a #=> [1, 2]
p b #=> [1, 2]
a += [3] # assigning a
p a #=> [1, 2, 3]
p b #=> [1, 2]
你不能。變量保存對值的引用,而不引用其他變量。
這裏就是你的示例代碼是做:
a = 5 # Assign the value 5 to the variable named "a".
b = a # Assign the value in the variable "a" (5) to the variable "b".
b = 4 # Assign the value 4 to the variable named "b".
a # Retrieve the value stored in the variable named "a" (5).
請參閱本文的主題進行更深入的討論:pass by reference or pass by value。
有沒有辦法做到這一點?在所有?即使有一些kludge?沒有可代表參考的值?我一直在發現,我可以很容易地做出各種瘋狂的紅寶石事情,我很驚訝,這是不可能的。感謝您的答覆。我想基本上隱藏真正的變量,我是否可以調整變量的設置方法以設置另一個變量?這會招致很多開銷嗎? – Orbit
不,不使用你的例子中的語法。你可以做一些花哨的技巧與'eval'編寫加載/存儲的值在其他變量,但僅此而已功能。看到這個[關於Ruby通過引用vs值的討論](http://www.ruby-forum.com/topic/41160)。 – maerics
這是錯的! b = a最強調不把b賦值5,因爲5是a中的值。 a中的值是對fixnum的引用。 b = a分配對b的引用。 –
我不是Ruby的專家。但是,對於一個技術上瘋狂克魯格...這將只有當你覺得通過eval
每次你用可變工作時間去工作:
>> a = 5
=> 5
>> b = :a
=> :a
>> eval "#{b} = 4"
=> 4
>> eval "#{a}"
=> 4
>> eval "#{b}"
=> 4
注意的b
直接使用還是會給你:a
,你可以「T用它不在eval
表達式:
>> b
=> :a
>> b + 1
NoMethodError: undefined method `+' for :a:Symbol
...當然也有一噸需要注意的地方。比如,你不得不捕捉binding
和更復雜的場景到處傳遞它...
'pass parameter by reference' in Ruby?
@ Paul.s有,如果你可以改變聲明的時候是一個答案包裝對象,但如果你只能控制的參考點,然後這裏有一個BasicReference
類我想:
class BasicReference
def initialize(r,b)
@r = r
@b = b
@val = eval "#{@r}", @b
end
def val=(rhs)
@val = eval "#{@r} = #{rhs}", @b
end
def val
@val
end
end
a = 5
puts "Before basic reference"
puts " the value of a is #{a}"
b = BasicReference.new(:a, binding)
b.val = 4
puts "After b.val = 4"
puts " the value of a is #{a}"
puts " the value of b.val is #{b.val}"
此輸出:
Before basic reference
the value of a is 5
After b.val = 4
the value of a is 4
the value of b.val is 4
如前所述,您正在使用的語法無法完成。剛拋出這個在那裏,雖然你可以做一個包裝類,這取決於你真正想做的事
ruby-1.8.7-p334 :007 > class Wrapper
ruby-1.8.7-p334 :008?> attr_accessor :number
ruby-1.8.7-p334 :009?> def initialize(number)
ruby-1.8.7-p334 :010?> @number = number
ruby-1.8.7-p334 :011?> end
ruby-1.8.7-p334 :012?> end
=> nil
ruby-1.8.7-p334 :013 > a = Wrapper.new(4)
=> #<Wrapper:0x100336db8 @number=4>
ruby-1.8.7-p334 :014 > b = a
=> #<Wrapper:0x100336db8 @number=4>
ruby-1.8.7-p334 :015 > a.number = 6
=> 6
ruby-1.8.7-p334 :016 > a
=> #<Wrapper:0x100336db8 @number=6>
ruby-1.8.7-p334 :017 > b
=> #<Wrapper:0x100336db8 @number=6>
只爲參考的緣故。
>> a = 5
=> 5
>> a.object_id
=> 11
>> b = a
=> 5
>> b.object_id
=> 11
>> b = 4
=> 4
>> b.object_id
=> 9
>> a.object_id
=> 11
# We did change the Fixnum b Object.
>> Fixnum.superclass
=> Integer
>> Integer.superclass
=> Numeric
>> Numeric.superclass
=> Object
>> Object.superclass
=> BasicObject
>> BasicObject.superclass
=> nil
我希望這可以讓我們更好地理解Ruby中的對象。在你覺得你想有直接的指針操作的情況下
一種選擇是使用哈希表,數組&字符串的替代方法。
這是因爲當你想有一個方法返回一個變量,一個進程的方法設置將在日後發生變化,並且不希望使用一個包裝對象的煩惱有用。
例如:
def hash_that_will_change_later
params = {}
some_resource.on_change do
params.replace {i: 'got changed'}
end
params
end
a = hash_that_will_change_later
=> {}
some_resource.trigger_change!
a
{i: 'got changed'}
它可能會更好通常使用明確的對象包裝對於這種情況,但這種模式是建築規格/異步測試的東西有用。
聽起來像指針...不是一個Ruby開發,但我不認爲指針在紅寶石。 – Dair
是的,Ruby中有指針。它們是對由它們的類類型創建的變量的引用。這裏b使其指向其中一個是,直到它做了一個新的指針本身引用Fixnum對象4. –
答案表明,=賦值創建這些指針和時類型相同的都指向相同的所有必須是改變參考對象和兩個相同的類型具有相同的對象引用。請記住他們爲什麼說「在Ruby中,一切都是對象」。在這方面有很多的事實。 –