Slashdot Mirror


Ruby 1.8.0 Released

waieitch writes "A long-waited new version of the scripting language, Ruby 1.8.0 has just been released. You can download from here, and the changelog is available. With many new libraries, say dRuby, ERB, REXML, this version is doubled by 1.6.8 in size."

21 of 97 comments (clear)

  1. Best. Clause. Evar. by gazbo · · Score: 4, Funny
    this version is doubled by 1.6.8 in size

    No more text.

  2. Former perl, python, java geek gone to Ruby by Fished · · Score: 4, Interesting
    For what it's worth, I've been using ruby for about six months, and am totally hooked. It is easily the best language I've ever used. Things that are idiosyncratic and difficult in other languages just flow in ruby. There are also many features to facilitate the way you actually *use* objects (e.g. to do object attributes, all you have to do is add "attr_writer attribute1, attribute2, attribute3" and "attr_reader attribute1, attribute2, attribute3") to the class defs. No more endless get and set functions all of which are more or less identical!

    This language is definitely worth a look. It's not just a python knock-off, as many have supposed -- it offers features python doesn't.

    --
    "He who would learn astronomy, and other recondite arts, let him go elsewhere. " -- John Calvin, commenting on Genesis 1
    1. Re:Former perl, python, java geek gone to Ruby by MarkusQ · · Score: 4, Interesting

      it had the same conceptual structure as Python, but the cryptic syntax of perl

      I'm not sure what language you looked at, but it doesn't sound like ruby.

      • Ruby is a deeply object oriented in the tradition of smalltalk; python is a superfically object oriented language more in the tradition of C++ or object pascal. Until recently, for example, you could not derive your own classes from the built in classes.
      • The basic syntax of ruby is very clean (a fact which is somewhat obscured by the "syntactic sugar" provided for some commonly used features (such as operators) and the provision of aliases for some global objects that are intended to ease the transition from perl). The basic syntax is:
        method_call ::= object.method_name arg1,arg2,...argn
        where object, method_name, and the arguments can all objects and can be given by named constants, literals, variables, or expressions (method calls). The only thing I really miss from python is the indentation (or rather, not having to explicitly delimit blocks, since I indent that way even when I don't have to).
      -- MarkusQ

    2. Re:Former perl, python, java geek gone to Ruby by tigersha · · Score: 4, Interesting

      The major improvement in Ruby over Python and C++ and most OO languages (but not Smalltalk) is the inclusion of code blocks that may be passed in as a parameter to a method and its widespread use throughout the libraries.

      For a simple example, look at this:

      x = [1,2,3,4]

      x.each do |e|
      puts e
      done

      This is NOT syntactic sugar. The list class has a each method that takes a piece of code as an argument and executes it for each element in the list. This can do the same as generators now coming into the new Python and is very similar to higher-order functions in functional languages.
      Basically the do...done part is a parameter (albeit a special one, a method may only have one).

      It is difficult and syntactiucally tricky to do this in most OO languages and trivial to add an each method (or whatever you want to call it) to your own classes. It is also extremely powerful way of doing many thing which requires a lot of messiness in other languages.

      This high-erorder code blocks now allow you to really do the everything-is-anobject thing because you MUST have code blocks to implement control structures such as if or while as an object. It is also very pervasively used in all collections and for instance in REXML where you can say

      x = some XML...

      x.each( xpath expression ) do |element| ...
      done

      Another example

      String.each_regexp( regexp ) do ... done

      Does the code for each place where the regexp was found in the string. Same sort of thing can be done for databases and so forth.

      Ruby also has things like mix-in classes which are usually dissed by OO theoreticians but turn out to be very useful. Mix-in classes were pioneered by some dialect of LISP and are a form of restricted multiple inheritance,. A class can inherit methods from other modules but not instance variables (except for its parent class). This allows you to this (this is pseudocode)

      myclass inherits Ord
      implement = and other operators in terms of and = (which are supplied by your class). And now your class implements all of these methods. This is again tricky to implement in traditional top-down inheritance trees. Think of Java's interface system, but with default implementations.

      This is used to great effect in the collections to implement many things in terms of some primitve operators.

      --
      The dangers of excessive individualism are nothing compared to the oppressiveness of excessive collectivism
    3. Re:Former perl, python, java geek gone to Ruby by RevAaron · · Score: 3, Interesting

      The basic syntax of ruby is very clean (a fact which is somewhat obscured by the "syntactic sugar" provided for some commonly used features (such as operators) and the provision of aliases for some global objects that are intended to ease the transition from perl). The basic syntax is:

      method_call ::= object.method_name arg1,arg2,...argn


      Along the same line, you could just as easily say that C++'s basic syntax is:

      method_call ::= object.method_name(arg1, arg2,...argn)

      and perl's:

      method_call ::= object->method_name(arg1, arg2,...argn)

      So C++ and Perl must be languages with simple, elegant and clean syntax, right? The method call syntax doesn't mean a thing. (well, if the language was particularily ugly it would- like some OO Cobol implementations)

      Ruby has substantially less syntax than Perl and C++, that much is true and pretty commonly known. However, IMHO, Ruby has a bit much syntax, compared to languages like Smalltalk or Scheme. Smalltalk is a language which manages to be expressive, but without the amount of syntax that Ruby has.

      --

      Working toward a usable PDA environment in the spirit of Newton OS: Dynapad
    4. Re:Former perl, python, java geek gone to Ruby by tcopeland · · Score: 3, Informative
    5. Re:Former perl, python, java geek gone to Ruby by MarkusQ · · Score: 3, Insightful
      I just don't like it when a language designer decides which ones he personally likes and includes them, without a possibility for users to create their own.

      Agreed. I'm not saying ruby is perfect, just that I like it slightly more than python and a lot more than perl. Its syntax isn't as clean as, say postscript, smalltalk, or scheme, but it's much better than bash, c++ or vb. Maybe somewhere around common lisp?

      My biggest gripes:

      • Blocks are litteraly a bag hung on the side. Needlessly ugly and limiting.
      • The typographic hungarian notation ($ for globals, capitals for constants, etc)
      • The premptive binding of literals to built in classes.
      • The perl compatibility frosting.
      It's still my scripting language of choice though. -- MarkusQ
    6. Re:Former perl, python, java geek gone to Ruby by Merk · · Score: 3, Insightful

      Someone already mentioned blocks, which is one big difference. The other is the true OO-ness of the language.

      irb(main):001:0> 1.type
      => Fixnum
      irb(main):002:0> 1.upto(3) {|i| puts i}
      1
      2
      3
      => 1
      irb(main):003:0> class MoreThanArray < Array; def is_even?; 0 == length % 2; end; end
      => nil
      irb(main):004:0> ma = MoreThanArray.new
      => []
      irb(main):005:0> ma[0] = "hello"
      => "hello"
      irb(main):006:0> ma.is_even?
      => false
      irb(main):007:0> ma[1] = "booga"
      => "booga"
      irb(main):008:0> ma.is_even?
      => true

      AFAIK, Python doesn't let you subclass built-in types, and it certainly doesn't let you treat integers as objects. At first glance, Ruby does appear similar to python, but if you really look at the OO aspects of the language you'll see some huge differences.

      As far as cryptic syntax... the only real similarities I've found between Perl and Ruby are the @ and $ symbols in front of variables. But in Perl @ is an array, and $ is a regular variable. In Ruby, @ is an instance variable of a class (accessible only within the class) and $ is a global variable. Ruby also keeps some of Perl's global variables, which allows for some cryptic looking syntax, but I rarely see or use them.

      In summary though, I don't know Python or Ruby well enough to enumerate all the differences between them. I just find that nearly every program I want to write becomes much shorter and easier in Ruby than it was in Python.

    7. Re:Former perl, python, java geek gone to Ruby by MarkusQ · · Score: 3, Insightful

      *laugh*

      I should have read your post before responding to __past__; I could have mostly said "see RevAaron's comment."

      The main point on which I disagree with you is that method calls are actually a small part of C++ & perl syntax. Control structures, expressions, etc. are all distinct (and ad hoc), because the types they opperate on (booleans, integers, etc.) are not objects. Conversely, in ruby everything is an object, and (if you want to) you can skip the sugar and write code that only passes messages to objects. This isn't as obvious as it is in (say) smalltalk, but it's at least true in ruby, whereas it's not in c++ or perl.

      -- MarkusQ

      P.S. I just thought of two even better examples of (syntactically) clean languages: both forth and prolog have very clean basic syntax.

    8. Re:Former perl, python, java geek gone to Ruby by Colonel+Panic · · Score: 4, Informative

      I thought that code blocks were a pretty lame excuse for proper functions-as-data, so I'm a little bit surprised to see them mentioned as a great feature. Did I miss something?

      You did.

      Code blocks are probably one of the most important features of Ruby that differentiates it from Python.


      From what I understand, code blocks are basically anonymous functions that the method they are passed to can only invoke with yield, right?


      wrong.

      Or is it possible to treat them as any other parameter, i.e. store them, pass them further around, take more than one etc?


      Yes. Yes. Yes. Yes (well, that last one is a qualified yes, if I understand your question correctly: you have to convert them to Proc objects before you can pass more than one of them to another method due to the fact that the '&' block delimiter in the method's parameter list can only be on the last parameter - it's not a big limitation).

      At first glance, code blocks don't seem that interesting, cool or useful, however, I was able to create a domain-specific hardware description language using them without the need to create any parser for that langauge. It was written in pure Ruby, but to the user it looks like another language in it's own right.

      So I could do things like (if you're familiar with VHDL this should look familiar):

      process(clk,rst) {
      if clk.event and clk == '1'
      counter.assign counter + 1
      elsif rst == '1'
      #do resest:
      counter.assign 0
      end
      }
      #

      It's all written in pure Ruby. The part between the '{' and '}' is a code block that's being passed to the process method which will execute the block whenever the value of clk or rst changes. So essentially, code blocks allowed me to make Ruby look a lot like VHDL. It looks very natural. AFAIK, this sort of thing is not (easily) doable in Python.

    9. Re:Former perl, python, java geek gone to Ruby by MarkusQ · · Score: 3, Insightful

      Yes, but it has *loads* less parentheses than scheme. :)

      If they bother you too much, try writing a little pre-processor (you can do it in about 20 lines of lex/yacc or so) that takes code with sailent structure (python style indentation) and spits it out with the parens?

      -- MarkusQ

    10. Re:Former perl, python, java geek gone to Ruby by xteddy · · Score: 3, Informative

      > * Blocks are litteraly a bag hung on the side. Needlessly ugly and limiting.

      Why do you feel they are ugly? Ok, they are not real functions like scheme has them, but Ruby wants to be an object oriented language, so it's ok that they are (can be transformed to) objects. Ruby is just consistent in not having any functions but only methods, so you have to use Proc#call(x) or Proc#[x] to call a procedure with arguments.

      They are real lexical closures, too, which wasn't mentioned in any thread before:

      def make_counter
      x = 0
      lambda do x += 1 end
      end

      c1, c2 = make_counter, make_counter
      c1.call # => 1
      c1.call # => 2
      c2.call # => 1
      c1.call # => 3
      c2.call # => 2

      > * The typographic hungarian notation ($ for globals, capitals for constants, etc)

      Hungarian notation encodes the type of a variable into the variable name. In Ruby the sigils are used to show the scope of the variables. You can see at one glance that @@foo is class variable, @bar is an instance variable and $baz is a global variable. I found this to be very useful while refactoring code.

      > * The premptive binding of literals to built in classes.

      In the case of small integers this is more time&space efficient and that's the price you have to pay.

      > * The perl compatibility frosting.

      There isn't really much left of perl compatibility and lots of perl's "features" are about to be deprecated. In general they aren't used very often by Ruby programmers. It's true that a lot of stuff looks like Perl, /^a.*/ and 1..10 for example, but unlike in Perl these are real objects and first class citizens in Ruby.

      > It's still my scripting language of choice though.

      Yeah, all scripting languages suck, Ruby just sucks less. *g*

    11. Re:Former perl, python, java geek gone to Ruby by MarkusQ · · Score: 4, Insightful

      > * Blocks are litteraly a bag hung on the side. Needlessly ugly and limiting.

      Why do you feel they are ugly? Ok, they are not real functions like scheme has them, but Ruby wants to be an object oriented language, so it's ok that they are (can be transformed to) objects.

      I don't object to blocks being objects; I object to them being arbitrarily forced into a special-syntax-optional-singleton-parameter gheto. Why can't I define a method that takes two or more blocks (e.g. if/then/else) with the same syntax I use for methods that take a single block? Why can't I introspect the structure of a block? Why the duality with Proc objects? In short, why aren't blocks first class objects?

      >* The typographic hungarian notation ($ for globals, capitals for constants, etc)

      Hungarian notation encodes the type of a variable into the variable name. In Ruby the sigils are used to show the scope of the variables.

      Hungarian notation (as the term is generaly used) encodes metadata into the variable name. Type, class, scope, storage class, etc. are all metadata. None of them should be duct-taped on to variable names (IMHO) because it obscures the intent of the code with a clutter of details about the means.

      You can see at one glance that @@foo is class variable, @bar is an instance variable and $baz is a global variable. I found this to be very useful while refactoring code.

      Sure, and I can imagine cases where it would be handy to have a language require that every variable reference includes a comma seperated list of the line numbers of each reaching assignment. It sure would make it easy to spot uninitialized variables, for example. But in general, it would make the code harder to read and maintain.

      More to the point, in ruby I'd like to be able to change the scope or storage class of an object reference without having to rename it.

      -- MarkusQ

    12. Re:Former perl, python, java geek gone to Ruby by Dan+Ost · · Score: 3, Informative

      Python doesn't let you subclass built-in types, and it certainly doesn't let you treat integers as objects.

      This is no longer true. As of Python 2.2, I'm pretty sure that both of these
      complaints have been addressed (the first one for sure).

      --

      *sigh* back to work...
    13. Re:Former perl, python, java geek gone to Ruby by ProfKyne · · Score: 4, Insightful

      AFAIK, Python doesn't let you subclass built-in types, and it certainly doesn't let you treat integers as objects.

      >>> class IntegerSubclass(int):
      ... pass
      >>> issubclass(IntegerSubclass, int)
      1

      In summary though, I don't know Python or Ruby well enough to enumerate all the differences between them. I just find that nearly every program I want to write becomes much shorter and easier in Ruby than it was in Python.

      Doesn't sound like you've really spent enough time in Python to make that comparison.

      --
      "First you gotta do the truffle shuffle."
    14. Re:Former perl, python, java geek gone to Ruby by xteddy · · Score: 5, Informative

      Why can't I define a method that takes two or more blocks (e.g. if/then/else) with the same syntax I use for methods that take a single block? Why can't I introspect the structure of a block? Why the duality with Proc objects? In short, why aren't blocks first class objects?

      To clarify this first: It's always possible to create multiple Proc objects with Proc.new, lambda or proc and pass them to a method.

      There are two reasons why there are blocks AND Proc objects:

      1. To use a block it's not necessary to create an object and that's good for the performance, e. g. if you have to iterate very often over some collection.
      2. Blocks are used for iterators and control structures, so Matz wanted them to look like those already did.

      It would perhaps be possible to have something like that:

      foo { ... } { ... }
      But there is an ambiguity because the first block could also be a hash constructor. I am not sure if it would be possible to solve that problem by changing the parser. You could limit yourself to use only do ... end with multiple blocks but I thinks that it's better not to have multiple do ... end blocks in one method call.

      BTW: The if/then/else is not a method call and the selectors consist only of a single word in Ruby unlike in Smalltalk. So it would require a big change to the language and the interpreter if blocks should be used there.

      Introspection of blocks is a good idea. Perhaps this will be possible if the new VM for Ruby 2.0, called Rite, is implemented. AFAIK it also should be possible to change code in the parse tree on the fly at arbitrary places then.

      More to the point, in ruby I'd like to be able to change the scope or storage class of an object reference without having to rename it.

      This is clearly a tradeoff. You can choose between having to look up the variables everytime you want to know their scope or between seeing it easily and change every variable if you want to extract a method. I think to choose the latter is a good choice for a language where you don't usually program in a code browser.

  3. correct link by oever · · Score: 3, Informative

    Here's the link to the changelog.

    --
    DNA is the ultimate spaghetti code.
  4. Re:Thanks, IE. Repost that isn't ruined by Fweeky · · Score: 3, Insightful
    Before someone whinges about named params:
    myServer = Server.new(:socket => foo, :something => bar, :security_mode => 2, :logfile_path => "/var/logs/speciallogs/")
    Which is syntax sugar for:
    myServer = Server.new({:socket => foo, :something => bar, :security_mode => 2, :logfile_path => "/var/logs/speciallogs/"})
    Since the { .. }'s can be missed at the end of the argument list.

    The { .. }'s are, of course, syntax sugar for:
    myServer = Server.new(Hash.new(:socket, foo, :something, bar, :security_mode, 2, :logfile_path, "/var/logs/speciallogs/"))
    Ruby's got bit of a sweet tooth, but luckily they're not rotting away like, uhm, certain other languages I could name ;)
  5. And yet another use... by Luk+Fugl · · Score: 3, Insightful

    One of the most useful instances of blocks I've found, and the one that truly converted me to Ruby, is registering them as callbacks.

    I was working on a program while learning Ruby where we wanted to filter an incoming stream of events and filter them out to handlers. Some events needed to be dispatched to multiple handlers, others could be ignored.

    The traditional approach would be to modify Dispatcher (any capitalized noun will be a class in my example here) and add some filtering logic each time a new filter needed to be added. But with procs (which are real closures, not just anonymous code blocks), I can do this:

    class Dispatcher
    include Singleton
    def initialize
    @callbacks = Array.new
    end
    def register(&callback)
    @callbacks.push callback
    end
    def receive(event)
    @callbacks.each.call(event)
    end
    end

    str = $stdout
    prefix = 'On STDOUT: '
    Dispatcher.instance.register do |event|
    str.puts prefix + event.to_s
    end

    str = $stderr
    prefix = 'On STDERR: '
    test = proc { |event| event.type == 'error'; }
    Dispatcher.instance.register do |event|
    return unless test.call(event)
    str.puts prefix + event.to_s
    end

    # ... later
    error = ErrorEvent.new('error text')
    noterror = NotErrorEvent.new('other text')
    Dispatcher.instance.receive(error)
    Dispat cher.instance.receive(noterror)

    # produces
    # "On STDOUT: error text" on stdout
    # "On STDERR: error text" on stderr
    # "On STDOUT: other text" on stdout

    Of course, this example is trivial, but the I'll admit I've since learned a way to do this in Perl, but it's much cleaner and all in all elegant the Ruby way.

    Jacob Fugal

    (ps. apparently <ecode> doesn't preserve my indentation, sorry...)

  6. Now will someone please document it? by PizzaFace · · Score: 3, Informative

    Ruby is a cool language, but someone has to break down and document it. There is quite a bit of not-quite-current documentation, including a great online version of Programming Ruby , but the official library reference is for 1.6 and the language reference is for 1.4. The lack of current documentation for 1.8 raises doubts about the consistency of the language's behavior, especially its more Perlish, do-what-I-mean features.

  7. Re:Hmmm... by Guido+von+Guido · · Score: 4, Informative

    You know, reading over the the information available for Perl 6, I get the idea that a lot of the improvements intended for Perl 6 were actually stolen from Ruby. As much as I love Perl, the OO implementation is a bolted-on, pain-in-the-ass kludge. Ruby's is an integral part of the language, and Ruby is a very nice language.