Question

Is is that I'm a newbie learning Ruby, or does it really have more ways to write (the same) things than Java/C#? Also, if it is more flexible than Java, are there any linguistic features of Ruby that are generally not used to avoid confusion?

Examples might be parallel assignment and all the different ways to write Strings, perhaps?

Note: I'm not asking for a comparison with Java/C#... just this language question, please...

Edit: I understand that C#, Java and Ruby are strongly typed, and that only Ruby (like Python and others) is dynamically typed (while Java/C# are statically typed). Some of the answers say that dynamically-typed languages are more flexible. Is this necessarily true, and how does it affect syntax? I am only asking about syntactic flexibility.

(PHP is also dynamically typed and it does not seem more flexible than Java/C#, as far as I've seen. Again, I mean in terms of syntax, not in terms of deployment nor any other aspect...)

Was it helpful?

Solution

I don't know Java or C#, but I let the fact that you can redefine how + works on numbers talk for itself.

OTHER TIPS

As for me the most used features in Ruby and missing in Java are code blocks/lambdas/closures.

Another great (but maybe dangerous) feature is open classes - you can change whatever class you want - add new method, change old, etc. You can even add method to specific object, not the whole class :).

Another dynamic language that's fairly similar to Ruby is Python. However, in the Zen of Python, one of the rules dictates that "there should be one, and only one, way of doing something". This is a polar opposite to Ruby which allows so much meta-programming that there are essentially an infinite number of ways to do the same thing.

That said, its somewhat ironic that up until Python 3.0 (aka: 3000) string and unicode values were different types. While it makes sense, people sometimes get into issues where they're converting between the two a lot to perform text operations.

If you have a choice, I'd almost recommend using Python as your introduction to dynamic languages. There's nothing wrong with Ruby, but you may find you'll run into fewer situations where the "right" way to do something isn't totally obvious.

In response to PHP being dynamically typed:

PHP's type system is flexible, allowing types to be automatically converted based on what context they're used in. This doesn't actually make then real dynamic types, however. The language itself is mostly static and won't allow you to add attributes to objects at runtime, for example (at least, the last time I checked).

Python, and quite possibly Ruby, are actually strongly typed, meaning you can confidently do type comparisons, and can't do PHP tricks like adding numeric strings to get a number. True dynamic languages also often allow for meta-classing where you can adjust the type of an instance or class, or add attributes to either, all at runtime.

Ruby is a dynamic language. C# and Java are both statically typed language with strong typing. C# in v4.0 will add dynamic features but till now, Java and C# have had a completely different and more strict paradigm than dynamic languages such as Ruby and Python.

I commented on rkj's answer above regarding lambda's. This code demonstrates the example you asked for;

def abs(n); (n < 0) ? -n : n; end
def square(n); n * n; end
def average(x, y); (x + y) / 2; end

def fixed_point(x, point, process, test)
  return point if test.call(x, point)
  fixed_point(x, process.call(x, point), process, test)
end

def sqrt(n)
  process = lambda {|n,g| average g, (n/g) }
  test = lambda {|n,g| abs(square(g) - n) < 0.001} 
  fixed_point(n, 1.0, process, test)
end

The first point to notice is that the fixed_point method handles the general idea of progressively applying a process to some data until it passes a certain test. The sqrt function defines the process of finding a square root and the test to determine when we're to be satisfied. These 'procedures' are then passed just like any other form of data so that fixed_point can work it's magic.

Instead of temporarily storing the process and test the whole thing could be anonymous. We could rewrite sqrt as;

def sqrt(n)
  fixed_point( n, 1.0, 
      lambda {|n,g| average g, (n/g)},
      lambda {|n,g| abs(square(g) - n) < 0.001} )
end

Without this ability, I would have to define both the process and the test as individual functions and create a special sqrt_fixed_point function to call them. As far as I'm aware Java can do something similar using Functors but I don't know enough to comment. The consensus I've seen in blogs or similar is that Java makes this so horrendously complicated that you'll get a nosebleed just trying it.

Of course, another option that Ruby gives is metaprogramming. I could rewrite sqrt so that it rewrites (on the fly) fixed_point using the correct process and test, but this is probably an abuse of the feature :-)

ps. The JoelOnSoftware link is posted deserves repeating; http://www.joelonsoftware.com/items/2006/08/01.html

All dynamically typed languages (like Ruby) usually are more flexible than statically typed ones (like Java). You don't have to fight with the type system, which you often end up doing in statically typed languages.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top