Rubyx OS - A Testament To The Power Of Ruby
Andrew Walrond writes "Rubyx the OS is created from source by rubyx the ruby script. Got it? The same small ruby script handles all subsequent package management, customised parallel and distributed user-mode package builds, and can create a live CD. For good measure, Rubyx (the os) sports an all new init and rationalised service management system written in ....can you guess?..."
FYI, there's another initiative to develop a fully Ruby-based operating system (including the kernel), though one wonder when -- if ever -- this project will deliver something usable.
If you had actually followed the link you would know that the whole OS is not written in ruby. It is Linux with a ruby installer and package system.
I'm not too sure how this isn't 'Rubyx, the Linux distribution with an installer/package manager written in Ruby'. If it had been written in any other language, would it still be cool?
If Rubyx is an OS then it does: Mandrake. The installer is written in Perl and the package management is done with Perl. That is all Rubyx is.
But if you want an example of extreme silliness in Perl you can look at http://freshmeat.net/projects/perlbox/ a Desktop Environment written in Perl.
Consensus gestalt that I've gotten as a Python user and reading a lot of debates on this topic is that structurally, Ruby is a little more pure OO then Python, but the practical differences seem minimal, especially after the type/class unification in Python. (Ruby advocates are proud of their block syntax but I'm yet to see something I don't immediately know how to write in Python, too; the question is which fits your mind better.)
Syntactically, Ruby is more like Perl. If you consider sigils an abomination upon the land, as I do (despite working professionally in Perl), then you'll want Python. If you consider them Larry Wall's gift to syntax, then you'll want Ruby.
The other thing is, if you're expecting to use a library of some kind, check for availability. Python has the edge right now AFAIK but that doesn't matter unless Python has something that Ruby doesn't that you need, or vice versa; for most people my impression is that the necessary modules are there in both languages.
I use Python mostly for "work", but I much prefer Ruby and try to use it whenever possible.
If you are a theoretical guy who loves a conceptually elegant and consistent language like Smalltalk or Scheme, you'll love Ruby. Ruby is so consistent, it's really lovely.
If you're more practical and need good documentation and extensive libraries, you'll probably be annoyed by it.
If you like to write programs FAST but not sacrifice readability like Perl, you'll really love Ruby. For instance in Ruby, you don't have to type "self" in method argument lists the way you do in Python. Ruby is 100% object oriented inside and out. Classes are first class objects, subclasses of Module objects. There are no "old style classes" or "new style classes", no cruft held over from previous versions of the language.
In Python, you have built-ins like "str()" which can call the __str__() method on an object. None of that kind of repetition in Ruby. Just call obj.str (or actually, obj.to_s) directly. You don't need the parens in that case.
Ruby has "blocks" which are a nice syntactic sugar for a whole class of operations. For instance a database transaction can be implemented as a block:
transaction { |t|
do stuff with t
more stuff
}
in Python that would be:
t = start_transaction()
try:
do stuff with t
more stuff
finally:
end_transaction()
The ruby version is easier to read.
If you want a large selection of tools and implementations, well, Ruby doesn't have too many like Python.
Also the Ruby community is still small and friendly. The python community is turning into the Perl community, in my opinion. A little arrogant.
Python is starting to look more and more like Ruby every revision though.
(note that '#' starts a comment, and => (value) in an end-of-line comment is showing the resulting value of an expression.)
You can collect as many matches as you want before you process them. There are no freaky, hard to remember variable names that you need to remember. You can still do it the Perlish way if you want to, but a lot of that stuff has been slowly made less desirable to use. I wouldn't be surprised (or upset) if they disappeared altogether in the future.
Then again, there may be the exact same thing in Python, and you're wondering why it's special. Since I went to Ruby straight from Perl, I wouldn't know.
(The code was pulled directly from online docs, so I'm not pretending I wrote it :)
At first glance, I thought this would be similar to Cleese, a Python-based operating system, but it isn't: RubyX is a distro with some stuff written in Ruby, and Cleese is an actual effort to write a kernel in Python. Not that it's progressing a lot, though... the CVS tree can be found here.
The character ("li" in Chinese) means "power" or "strength" (in both physical and spiritual senses of the word).
The |x| is a block parameter list. Blocks are Ruby's way to emulate higher order functions.
[ 1, 2, 3 ].each { |x| puts x }
would print "1", "2" and "3" in three different lines.
The block parameters are very clever, you can also put something else than only variables there. If you want to compute the sum of the products of some pairs, you could do it that way:
a = [[1, 4], [2, 5], [3, 6]]
sum = a.inject(0) { |s, (x, y)| s + x * y }
The block would first be called with s = 0 and (x, y) = [1, 4], that would assign x to 1 and y to 4.
The inject would compute
s = 0 + 1 * 4
s = 4 + 2 * 5
s = 14 + 3 * 6 = 32
by calling the block three times once for every pair in the list and adding the results in the s and returning the result s.
The ||-syntax looks very similar to the Smalltalk syntax for local variables. Ruby is very strongly influenced by Smalltalk. The inject method name stems also from Smalltalk. You can use blocks to make sure something is done after a block of code has been executed instead of using destructors or finalizers. An example would be to close a file after reading it:
File.open("/etc/passwd") do |f|
puts f.read.count("\n") # => number of lines
end # => file f is closed here
do...end is equivalent to { } and usually used if the block is not an oneliner. Readability is actually very important in Ruby culture.
Ruby has an exception handling that is very similar to Python's, but the keywords seem to be blatantly stolen from Eiffel's Design By Contract. The transaction example from above could also be coded that way in Ruby:
t = start_transaction()
begin
do stuff with t
more stuff
rescue => e
puts "Caught an exception: #{e}"
ensure
t.end_transaction
end
I don't think that Ruby has a problem wth "non-alphanumeric" characters - it uses them very wisely, actually. I remember that Python uses lots of __foo__ and """bar""" - that really makes me feel uncomfortable when I have to read Python code!