Tuesday, March 27, 2007

As Borat would Say: Ruby Makes Me More Productive ...Pause... NOT!

So there are are lots of claims/hype/nonsense about how Ruby makes more productive. I guess those folks have never used Python: which "just work" and has a not only a richer built-in API but one that is much better documented.

A case in point:

So I've just spent the last hour (maybe up to two now..) or so trying to get basic OS information, you know that is built in the standard python library platform so you can do stupide Hello World style stuff like:

root@ubuntu:~/rubygems-0.9.2# python
Python 2.4.3 (#2, Oct 6 2006, 07:52:30)
[GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.uname()
('Linux', 'ubuntu', '2.6.15-23-server', '#1 SMP Tue May 23 15:10:35 UTC 2006', 'i686', '')
>>>


Which of course isn't built into the standard library and if it were you wouldn't be able to find out if it were anyway.

All bitterness behind me, I was pretty excited when I found sysutils on RubyForge. That looks niiiiice.

First I try OSX... where 50% of the gem's fail to install (but to the projects credit there are some tracker items opened this month), but sys-uname appears to sort of install, but of course it doesn't work when I try to use it:

franz-g4:~ mdfranz$ gem list | grep sys
sys-uname (0.7.4)
sys-uptime (0.4.5)
A Ruby interface for getting system uptime information.
franz-g4:~ mdfranz$ irb
irb(main):001:0> require 'sys/uname'
LoadError: no such file to load -- sys/uname
from (irb):1:in `require'
from (irb):1


What could it be? Dueling Ruby's (I use ruby from ports in /opt in addition to the built in "broken" Ruby in Tiger) Maybe it is an OSX (or PPC) issue because of course nobody uses Ruby on OSX, well except all those fancy rails developers who have no use for APIs like these.

So I switch over to OpenBSD 4.1. Download gems 0.9.2. And try to install. More than half fail with even worse errors --configure errors. I try the source for sys-uname and it sort of installs. Ri/Rdoc don't work (path problems?!) but I manage to find the API documentation deep in /usr/local/lib/ after installing links from ports, since lynx doesn't support frames.

But as you can see installing from source is a bad idea, because apparently that only works for Win32, which makes complete sense since BSD folks only install binaries and Windows users have this obscure method involving something called "make"

# irb
irb(main):001:0> require 'sys/uname'
LoadError: no such file to load -- win32ole
from /usr/local/lib/ruby/site_ruby/1.8/sys/uname.rb:1:in `require'
from /usr/local/lib/ruby/site_ruby/1.8/sys/uname.rb:1
from (irb):1:in `require'
from (irb):1
irb(main):002:0> # vi /usr/local/lib/ruby/site_ruby/1.8/sys/uname.rb
# irb
irb(main):001:0> require 'sys/uname'
=> true
irb(main):002:0> import Sys
NoMethodError: undefined method `import' for main:Object
from (irb):2
irb(main):003:0> Uname
NameError: uninitialized constant Uname
from (irb):3
irb(main):004:0> include Sys
=> Object
irb(main):005:0> Uname.sysname
NameError: uninitialized constant Sys::Uname::WIN32OLERuntimeError
from /usr/local/lib/ruby/site_ruby/1.8/sys/uname.rb:101:in `sysname'
from (irb):5
from :0
irb(main):006:0> Sys
=> Sys
irb(main):007:0> Sys.methods
=> ["methods", "instance_eval", "display", "object_id", "dup", "instance_variables", "include?", "private_instance_methods", "instance_of?", "protected_method_defined?", "extend", "const_defined?", "eql?", "name", "public_class_method", "hash", "id", "singleton_methods", "autoload", "taint", "constants", "frozen?", "instance_variable_get", "kind_of?", "ancestors", "to_a", "private_class_method", "const_missing", "instance_method", "type", "instance_methods", "protected_methods", "method_defined?", "instance_variable_set", "const_get", "is_a?", "respond_to?", "to_s", "module_eval", "class_variables", "class", "<=>", "<", "tainted?", "private_methods", "==", "public_instance_methods", "autoload?", "__id__", "===", "public_method_defined?", ">", "included_modules", "nil?", "untaint", "const_set", "method", ">=", "<=", "send", "inspect", "class_eval", "clone", "=~", "protected_instance_methods", "public_methods", "private_method_defined?", "__send__", "equal?", "freeze"] irb(main):008:0> Uname
=> Sys::Uname
irb(main):009:0> Uname.methods
=> ["methods", "instance_eval", "display", "object_id", "dup", "instance_variables", "include?", "private_instance_methods", "instance_of?", "protected_method_defined?", "extend", "const_defined?", "eql?", "nodename", "name", "public_class_method", "hash", "new", "id", "singleton_methods", "release", "autoload", "taint", "constants", "frozen?", "instance_variable_get", "parse_ms_date", "kind_of?", "ancestors", "to_a", "private_class_method", "const_missing", "instance_method", "type", "protected_methods", "instance_methods", "uname", "superclass", "convert", "method_defined?", "instance_variable_set", "const_get", "is_a?", "respond_to?", "to_s", "machine", "module_eval", "class_variables", "allocate", "class", "<=>", "<", "tainted?", "private_methods", "==", "public_instance_methods", "autoload?", "__id__", "===", "public_method_defined?", ">", "sysname", "included_modules", "nil?", "untaint", "const_set", "method", ">=", "<=", "send", "inspect", "class_eval", "version", "clone", "=~", "protected_instance_methods", "public_methods", "private_method_defined?", "__send__", "equal?", "freeze"] irb(main):010:0> Uname.machine
NameError: uninitialized constant Sys::Uname::WIN32OLERuntimeError
from /usr/local/lib/ruby/site_ruby/1.8/sys/uname.rb:140:in `machine'
from (irb):10
from :0


So this obviously isn't working. Delete the package I installed from source which is obviously only meant to be used on Windows. So I think to myself, maybe shouldn't be wasting my time with Ruby on non-standard OS's like OpenBSD and OSX that nobody in their right mind uses in corporate environments. Things will fair much better on Linux:

root@ubuntu:~# apt-get install ruby-1.8.4
Reading package lists... Done
Building dependency tree... Done
E: Couldn't find package ruby-1.8.4
root@ubuntu:~# apt-get install ruby
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
libruby1.8 ruby1.8
Suggested packages:
ruby1.8-examples rdoc1.8 ri1.8
The following NEW packages will be installed:
libruby1.8 ruby ruby1.8
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 1627kB of archives.
After unpacking 6058kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://security.ubuntu.com dapper-security/main libruby1.8 1.8.4-1ubuntu1.3 [1420kB]
Get:2 http://us.archive.ubuntu.com dapper/main ruby 1.8.2-1 [19.0kB]
Get:3 http://security.ubuntu.com dapper-security/main ruby1.8 1.8.4-1ubuntu1.3 [189kB]
Fetched 1627kB in 3s (408kB/s)
Selecting previously deselected package libruby1.8.
(Reading database ... 60327 files and directories currently installed.)
Unpacking libruby1.8 (from .../libruby1.8_1.8.4-1ubuntu1.3_i386.deb) ...
Selecting previously deselected package ruby1.8.
Unpacking ruby1.8 (from .../ruby1.8_1.8.4-1ubuntu1.3_i386.deb) ...
Selecting previously deselected package ruby.
Unpacking ruby (from .../archives/ruby_1.8.2-1_all.deb) ...
Setting up libruby1.8 (1.8.4-1ubuntu1.3) ...

Setting up ruby1.8 (1.8.4-1ubuntu1.3) ...
Setting up ruby (1.8.2-1) ...
root@ubuntu:~# ruby -v
ruby 1.8.4 (2005-12-24) [i486-linux]
root@ubuntu:~# wget http://rubyforge.org/frs/download.php/17190/rubygems-0.9.2.tgz
--21:07:50-- http://rubyforge.org/frs/download.php/17190/rubygems-0.9.2.tgz
=> `rubygems-0.9.2.tgz'
Resolving rubyforge.org... 205.234.109.18
Connecting to rubyforge.org|205.234.109.18|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://rubyforge.iasi.roedu.net/files/rubygems/rubygems-0.9.2.tgz [following]
--21:07:51-- http://rubyforge.iasi.roedu.net/files/rubygems/rubygems-0.9.2.tgz
=> `rubygems-0.9.2.tgz'
Resolving rubyforge.iasi.roedu.net... 192.129.4.120
Connecting to rubyforge.iasi.roedu.net|192.129.4.120|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 197,256 (193K) [application/x-gzip]

100%[====================================>] 197,256 203.00K/s

21:07:52 (202.37 KB/s) - `rubygems-0.9.2.tgz' saved [197256/197256]

root@ubuntu:~# tar xzvf rubygems-0.9.2.tgz

[snip]

root@ubuntu:~# cd rubygems-0.9.2
root@ubuntu:~/rubygems-0.9.2# ls
bin examples lib post-install.rb redist setup.rb
ChangeLog gemspecs LICENSE.txt Rakefile Releases test
doc GPL.txt pkgs README scripts TODO
root@ubuntu:~/rubygems-0.9.2# vi README
root@ubuntu:~/rubygems-0.9.2# ruby setup.rb
---> bin

snip

<--- bin ---> lib
source_info_cache.rb /usr/local/lib/site_ruby/1.8/rubygems
install source_info_cache_entry.rb /usr/local/lib/site_ruby/1.8/rubygems
install specification.rb /usr/local/lib/site_ruby/1.8/rubygems
install timer.rb /usr/local/lib/site_ruby/1.8/rubygems
install user_interaction.rb /usr/local/lib/site_ruby/1.8/rubygems
install validator.rb /usr/local/lib/site_ruby/1.8/rubygems
install version.rb /usr/local/lib/site_ruby/1.8/rubygems
<--- lib/rubygems <--- lib Successfully built RubyGem Name: sources Version: 0.0.1 File: sources-0.0.1.gem Removing old RubyGems RDoc and ri... /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- rdoc/rdoc (LoadError) from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' from /root/rubygems-0.9.2/./post-install.rb:103:in `install_rdoc' from /root/rubygems-0.9.2/./post-install.rb:118:in `try_run_hook' from setup.rb:584:in `run_hook' from setup.rb:1322:in `exec_task_traverse' from setup.rb:1175:in `exec_install' from setup.rb:894:in `exec_install' from setup.rb:712:in `invoke' from setup.rb:681:in `invoke' from setup.rb:1359


In hindsight, this is because I haven't installed the rdoc package, but I'm so frustrated I go back to OpenBSD. So I delete the what I've installed from source and try again with the GEM. Just for grins I go into the test script:

# cd /tmp
# ls
sys-uname-0.7.4 sys-uname-0.7.4.tar.gz
# cd sys-uname-0.7.4 # ls
CHANGES README ext sys
MANIFEST doc install.rb sys-uname.gemspec
Makefile examples lib test
# cd test/ # ls
tc_uname.rb
# ./tc_uname.rb ksh: ./tc_uname.rb: cannot execute - Permission denied
# ruby tc_uname.rb Loaded suite tc_uname
Started
"architecture" test skipped on this platform
."srpc_domain" test skipped on this platform
."hw_provider" test skipped on this platform
."hw_serial_number" test skipped on this platform
."id" test skipped on this platform
."isa_list" test skipped on this platform
.."model" test skipped on this platform
.."platform" test skipped on this platform
.."srpc_domain" test skipped on this platform
.....
Finished in 0.018236 seconds.

16 tests, 22 assertions, 0 failures, 0 errors

Ok so maybe something is working.

# irb
irb(main):001:0> require 'sys/uname'
=> true
irb(main):002:0> import Sys
NoMethodError: undefined method `import' for main:Object
from (irb):2
irb(main):003:0> include Sys
=> Object
irb(main):004:0> Uname
=> Sys::Uname
irb(main):005:0> Uname.methods
=> ["methods", "instance_eval", "display", "sysname", "object_id", "dup", "instance_variables", "include?", "private_instance_methods", "instance_of?", "protected_method_defined?", "extend", "const_defined?", "eql?", "name", "public_class_method", "hash", "new", "id", "singleton_methods", "nodename", "autoload", "taint", "constants", "frozen?", "instance_variable_get", "kind_of?", "ancestors", "to_a", "private_class_method", "const_missing", "instance_method", "type", "protected_methods", "instance_methods", "superclass", "machine", "method_defined?", "instance_variable_set", "const_get", "is_a?", "respond_to?", "to_s", "module_eval", "class_variables", "allocate", "class", "<=>", "<", "tainted?", "private_methods", "==", "public_instance_methods", "autoload?", "__id__", "===", "public_method_defined?", ">", "release", "included_modules", "nil?", "untaint", "const_set", "method", ">=", "<=", "send", "inspect", "class_eval", "version", "clone", "=~", "protected_instance_methods", "public_methods", "private_method_defined?", "uname", "__send__", "equal?", "freeze"] irb(main):006:0> Uname.sysname
=> "OpenBSD"
irb(main):007:0> Uname.display
Sys::Uname=> nil
irb(main):008:0> Uname.name
=> "Sys::Uname"
irb(main):009:0> Uname.machine
=> "i386"
irb(main):010:0> Uname.uname

=> #struct sysname="OpenBSD" nodename="pre41.my.domain" machine="i386"version="GENERIC#0" release="4.1"

WOWIE-WOO-IE!

Update: things are going much better after reading Rubygems got you down.

# gem install sys-uname
ERROR: While executing gem ... (NoMethodError)
undefined method `refresh' for #
# find / -name "source_cache" -exec rm {} \;
# gem update
Updating installed gems...
^C^C^C^C^[[CBulk updating Gem source index for: http://gems.rubyforge.org
Gems: [] updated
# gem install sys-uname
Bulk updating Gem source index for: http://gems.rubyforge.org
Select which gem to install for your platform (i386-openbsd4.0)
1. sys-uname 0.7.4 (ruby)
2. sys-uname 0.7.4 (mswin32)
3. sys-uname 0.7.3 (ruby)
4. sys-uname 0.7.2 (ruby)
5. Skip this gem
6. Cancel installation
> 1
Building native extensions. This could take a while...
Successfully installed sys-uname-0.7.4
Installing ri documentation for sys-uname-0.7.4...
Installing RDoc documentation for sys-uname-0.7.4...
# irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'sys/uname'
=> true
irb(main):003:0> include Sys
=> Object
irb(main):004:0> Uname
=> Sys::Uname
irb(main):005:0> Uname.methods
=> ["to_a", "to_yaml_style", "respond_to?", "ancestors", "module_eval", "const_missing", "type", "yaml_as", "protected_methods", "instance_methods", "public_method_defined?", "superclass", "eql?", "version", "instance_variable_set", "const_get", "is_a?", "autoload?", "machine", "hash", "to_s", "to_yaml_properties", "send", "display", "class_eval", "class_variables", "class", "method", "private_methods", "tainted?", "public_instance_methods", "__send__", "private_method_defined?", "untaint", "included_modules", "const_set", "id", "release", "instance_eval", "inspect", "require_gem", "taguri", "clone", "public_methods", "yaml_tag_class_name", "taguri=", "to_yaml", "protected_instance_methods", "extend", "protected_method_defined?", "gem", "freeze", "require", "yaml_tag_read_class", "public_class_method", "allocate", "__id__", "<=>", "<", "uname", "methods", "==", "===", ">", "dup", "nil?", "instance_variables", "include?", "private_instance_methods", ">=", "instance_of?", "const_defined?", "sysname", "<=", "name", "private_class_method", "autoload", "=~", "object_id", "new", "singleton_methods", "method_defined?", "taint", "equal?", "instance_method", "instance_variable_get", "frozen?", "constants", "kind_of?", "nodename", "yaml_tag_subclasses?"]
irb(main):009:0> Uname.uname
=> #sysname="OpenBSD" nodename="xxxxx.hewitt.com" machine="i386" version="GENERIC#1107" release="4.0">

No comments: