Category talk:Ruby

From Rosetta Code

Pass by reference?

How is Ruby pass-by-reference? The passing of values in Ruby (which are all references) has exactly the same semantics as the passing of reference type values in Java. (Is it not?) Java is listed as pass-by-value only. So to be consistent we should list Ruby as pass-by-value. --76.91.63.71 20:02, 2 August 2009 (UTC)

Ruby is pass-by-value as you say. I changed the page from 'parampass=reference' to 'parampass=value'. I also changed it from 'execution=bytecode' to 'execution=interpreted'. Ruby 1.9 compiles a program to bytecode and executes the bytecode, but this is an internal detail of the interpreter. There is no Java .class or Python .pyc file. --Kernigh 01:44, 9 March 2011 (UTC)

This program shows that Ruby passes by value:

<lang ruby># Ruby def f(x)

 x = "different string"

end

x = "original string" f(x) puts x # => "original string"</lang>

If Ruby would pass by reference, then this program would print "different string". But it prints "original string", because the two x have distinct values. Contrast Perl, which passes by reference:

<lang perl># Perl sub f {

 $_[0] = "different string";

}

my $x = "original string"; f($x); print "$x\n"; # => "different string"</lang>

This program prints "different string" because Perl passes $x by reference, so $_[0] is an alias of $x. (Many Perl subs use my $x = shift; to create a distinct value.)

Ruby would act like Perl if the Ruby program would use x.replace "different string". This would work because x is a reference to a mutable string. I think that Ruby is pass by value because I can use assignment to change the value of x, to refer to some other string. I am reverting the page to 'parampass=value', after 74.215.210.198 reverted the page to 'parampass=reference', after I changed it to 'parampass=value'. --Kernigh 02:31, 16 March 2011 (UTC)


Ruby passes by reference since it don't make copies of the objects when passing then to a method. Look:

<lang ruby>def f(x)

 x.replace("different string")
 x << " from method"
 x = "another variable"

end

x = "original string" f(x) puts x # => "different string from method"</lang>

All variables are, internally, pointers to objects, so, when I pass the variable, it passes the reference to the object, that allow me to change directly the object. But I can't set the variable because when you set it inside the method you are creating another variable that have nothing to do with the old one. I'm reversing the change on "parampass", to 'reference'.

189.104.25.246 02:03, 10 July 2011 (UTC)

With Ruby, x = "string" never creates a variable, unless there is no x in scope. I can check this with a closure:
<lang ruby>def f(x)
 x.replace("different string")
 x << " from method"
 $p = proc { x }
 x = "another variable?"

end

x = "original string" f(x) puts x # => "different string from method" puts $p.call # => "another variable?"</lang>

Some other languages are simpler. With Common Lisp, (let ((x "string")) ...) creates a variable and (setq x "string") sets it. With Factor (inside a [let ... ] block), "string" :> x! creates it and "string" x! sets it. With Ruby, x = "string" can either create it or set it. This is only important if some closure or binding captures x. --Kernigh 04:00, 11 August 2011 (UTC)
Ruby, Python, Scheme, Java (when talking about objects), etc.; all of these pass by value. People who argue against pass by value seem to have a different idea of what is being passed. They think that you are "passing" an "object". But that fact is, in all these languages, the values in the language are "references" (or pointers, or whatever you call them; the idea is the same: there is a level of indirection). You can never manipulate an "object" directly in these languages; you can only do it through references (you can see that values are references by assigning one variable to another and seeing that they point to the same object, hence a reference is copied, not the object). So when you are passing stuff, the values you are passing are the references, and those references are copied. In a pass-by-reference language, you would be able, in the function, to change the thing that is passed -- the reference -- in the calling scope; but you can't in Ruby; you can verify this by checking x.object_id to see that the reference still points to the same object.
People tend to point out that if these objects are mutable (e.g. String in Ruby), then it is possible to use its mutation methods to mutate its internal state in a way that is visible to other people who have a reference to the same object; but this is irrelevant. Because it is not the object that is being passed -- it is the reference. We can separate out the mutation issue by using an object type that is not mutable, e.g. take an integer or float or boolean in Ruby, and passing it; see that you cannot affect it in the calling scope; whereas in a true pass-by-reference language, you always can. --Spoon! 07:01, 11 August 2011 (UTC)
That said, note that this point of view is that you cannot pass an object to a method. --Rdm 12:33, 11 August 2011 (UTC)
Right; not only can you not pass an object, the point of view is that no expression in the language has the value of an object, only the value of a reference. This is the same point of view as in Java, Python, etc. Whatever we decide has to be consistent across all these languages. --Spoon! 19:44, 11 August 2011 (UTC)

Phantom categories and Ruby's standard library

A few parts of Ruby's standard library have their own categories.

  1. require 'curses' => Category:Curses
  2. require 'rexml/document' => Category:REXML
  3. require 'tk' => Category:Ruby/Tk

I am not wanting categories for most other parts of the standard library. I destroyed 11 phantom categories by removing all their members.

  1. Category:bigdecimal (2 members)
  2. Category:complex.rb (1 member)
  3. Category:dRuby (1 member)
  4. Category:fileutils.rb (1 member)
  5. Category:mathn (1 member)
  6. Category:matrix (2 members)
  7. Category:matrix.rb (3 members)
  8. Category:minitest (1 member)
  9. Category:optparse (1 member)
  10. Category:prime (1 members)
  11. Category:test/unit (2 members)

A phantom category is a category with some members, but no category page. Templates like {{libheader|prime}} did put pages in these categories. I started to destroy these categories after someone confused Category:prime with Category:Prime Numbers (ref 1 and ref 2). I think that many contributors will use the standard library without adding categories. I see code that calls require 'find' or require 'securerandom' without a category. --Kernigh 03:49, 27 August 2011 (UTC)