2

Suppose you have the following class:

class Klass
  include SomeModule
  def some_method
    SomeModule::some_proc.call(self)
  end
end

What is actually going on here? Is the ruby loading a whole copy of the instance of Klass referred to by 'self' into memory and passing that copy into the proc being called by 'some_method'? Or is there only one copy of the instance loaded into memory?

kempchee
  • 470
  • 1
  • 4
  • 17

1 Answers1

3

There is only one instance loaded into memory and Ruby will pass a reference/pointer to it to the proc you are calling.

Unlike some other languages, Ruby never automatically makes a copy of an object. You are usually passing around references to one object. You can verify that two objects have the same identity by calling object_id (or inspect) on each of them and making sure the IDs are the same. You can make a copy explicitly by calling dup or clone on the object.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • "Ruby never automatically makes a copy of an object" – not quite true, at least for MRI. Strings are copied when used as Hash keys, and although "real Ruby objects", Fixnums (and some other instances, like `true`) are not passed by reference. – DMKE Jun 24 '14 at 22:10
  • @DMKE: Nothing is ever passed by reference in Ruby, so your last sentence is at least redundant and at worst misleading, since it can be understood to imply that objects which aren't `Fixnum`s or `true` are passed by reference. – Jörg W Mittag Jun 24 '14 at 22:42
  • Ok now I'm confused; if nothing is passed by reference, how is it passed? And is there a difference between objects such as Fixnums and custom defined objects? – kempchee Jun 25 '14 at 02:19
  • To disagree with Jorg, I would say that all things are passed by reference in Ruby but I am not trying to make any distinction between references and pointers. If you are talking about a plain-old Ruby object (i.e. instance of your `Klass`) then Ruby keeps track of a 32-bit (or 64-bit for 64-bit machines) pointer to that object's memory, and this pointer is what gets passed around. Fixnums, Symbols, nil, false, and true act like immutable objects that are passed around by reference, but for efficiency they don't actually use pointers to memory locations, but that's an implementation detail. – David Grayson Jun 25 '14 at 02:23
  • I learned a lot about how Ruby works by studying how to write C extensions: https://speakerdeck.com/lvrug/extending-ruby-with-c-by-david-grayson – David Grayson Jun 25 '14 at 02:26
  • @kempchee: Ruby is pass-by-value, like almost all modern languages: http://StackOverflow.Com/a/19889911/2988 . You can check it with a simple program: `def is_ruby_pass_by_value?(foo); foo = 'No, Ruby is pass-by-reference.' end; bar = 'Yes, of course, Ruby *is* pass-by-value!'; is_ruby_pass_by_value?(bar); p bar # 'Yes, of course, Ruby *is* pass-by-value!'` – Jörg W Mittag Jul 01 '14 at 10:20
  • Jorg, now try writing `foo.replace` instead of `foo =` and you get a different answer. That means that foo and bar are references/pointers to the same string. – David Grayson Jul 01 '14 at 12:45
  • @DavidGrayson: Of course, you get a different answer if you ask a different question. But if you change the code in the way you propose it will no longer check whether Ruby is pass-by-value (which it clearly *is*, as my code demonstrates) but rather check whether Ruby has mutable state (which it *has*, noone here ever claimed that Ruby was a purely functional referentially transparent language, so checking that wouldn't provide any value here). – Jörg W Mittag Jul 09 '14 at 14:23
  • Ok, I think we understand eachother. I don't know the specific computer science definitions for "pass by reference" and "pass by value". (Where do you get your definitions from?) From what you say it sounds like Ruby technically does the latter, but I think it is confusing when you say that because it seems to imply that large objects are being copied when a method is called, which is what this discussion should be about. Anyway, I avoided using those technical terms in my actual answer so hopefully you can agree that the wording of my answer is okay. – David Grayson Jul 09 '14 at 15:44