http://www.perlmonks.org?node_id=509550


in reply to Re^2: OT: Ruby On Rails - your thoughts?
in thread OT: Ruby On Rails - your thoughts?

When DBIx::Class can do what Re^2: OT: Ruby On Rails - your thoughts? describes, then I'll be impressed. Why isn't DBIx::Class required by Catalyst vs. Class::DBI? Why isn't DBIx::Class being trumpeted to the rooftops? Why is CDBI still forced onto poor unsuspecting users?!? The world wants to know!

A huge win that ActiveRecord and Rails have is the fact that they use Ruby. For example, here's some code I wrote in Ruby that directly uses DBI.

require 'dbi' insert_sql = "some SQL statement" DBI.connect( 'dbi:Mysql:database=some_db;host=some_host', 'user', 'pas +sword' ) { |dbh| dbh.prepare( insert_sql ) { |sth| File.open( File.join( File.dirname(__FILE__), 'some_file.txt' ) ) { |file| # Strip off the first two lines (1..2).each { file.gets } file.each { |line| fields = line.strip.split( ',' ) fields.each { |field| field.gsub!(/"/, '') field.strip! } # Adjust for stoopidity fields[5] = (2 - fields[5].to_i) + 1 ary = [ fields.values_at(1..4, 4..5), 0, 0 ].flatten sth.execute( *ary ) } } } }

This is the equivalent code in Perl.

use DBI; use FindBin; use File::Spec; use IO::File; my $insert_sql = "some SQL statement"; my $dbh = DBI->connect( 'dbi:Mysql:database=some_db;host=some_host', 'user', 'password', { PrintError => 0, RaiseError => 1, }) or die "Cannot connect\n"; my $sth = $dbh->prepare( $insert_sql ); my $fh = IO::File->new( File::Spec->catfile( $FindBin::Bin, 'some_file +.txt' ) ) or die "Cannot open file"; scalar(<$fh>) for 1 .. 2; while ( my $line = <$fh> ) { chomp $line; my @fields = map { s/"//g; s/^\s+//; s/\s$//; $_ } split ',', $line; $fields[5] = (2 - $fields[5]) + 1; $sth->execute( @fields[1..4], @fields[4..5], 0, 0 ); } $sth->finish; $dbh->disconnect;

Which one is easier to read? Which one is easier to modify? Which one is easier to verify in terms of variables staying in scope? And, this is an example that is not only written by someone who's an expert in Perl vs. a novice in Ruby, but it's an example that's catering to Perl's strengths! And, Ruby still is a win in my eyes. Just imagine this kind of code within a much larger application. By using the first-class blocks that Ruby provides, that's a huge amount of scoping ... for free!

The only true win Perl has in those snippets is the array slicing at the bottom. I'm pretty sure that's because I suck at Ruby and not because Ruby sucks vis-a-vis Perl.

Rails may suck relative to Catalyst, but it couldn't be written in Perl (or Java or any other language). I hate to say it, sri, but Catalyst could be written in Ruby.

For the record, Catalyst is my preference for new webapp development in Perl and I think it's an excellent step forward. Rails is my first choice for new webapp development in any language.


My criteria for good software:
  1. Does it work?
  2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Replies are listed 'Best First'.
Re^4: OT: Ruby On Rails - your thoughts?
by sri (Vicar) on Nov 17, 2005 at 22:15 UTC
    As said before, DBIx::Class (DBIx::Class::Loader) does all that and much more, it also requires less code than your Rails example btw.
    package MyApp::Model::DBIC; use strict; use base 'Catalyst::Model::DBIC'; __PACKAGE__->config( dsn => 'dbi:SQLite:/Users/sri/MyApp/test.db', relationships => 1 ); 1;
    Thats all you need, table classes are generated and releationships auto-detected by analyzing foreign keys.
    You don't even have to write it by hand, Catalyst has helpers to do it for you. ("script/myapp_create.pl model DBIC DBIC dbi:SQLite:/Users/sri/MyApp/test.db")

    Bundle::Catalyst suggests only DBIx::Class, definitely not Class::DBI.

    Yes Ruby looks a bit cleaner in "your" examples, but bad programmers write bad code in any language.

    Ruby is also missing a lot that disqualifies it for me, especially Multiple Inheritance, i like NEXT and Class::C3 very much. (mixins are no alternative!)
    Not to mention the bad performance and lack of modules...

    So what exactly can't be written in Perl?!?!

    Do you really think a tight integrated framework for Perl makes sense? Why?
    The Perl community is very fragmented, we have many alternatives(TIMTOWTDI), TT, HTML::Mason, HTML::Template, DBIx::Class, Tangram, Alzabo, SPOPS... which two components would you choose for tight integration? They all have their strengths and weaknesses, so why not choose the best for the task at hand? Why not use multiple template engines, multiple orm's in the same application?

    So far i've not even seen a single Rails app dealing with more than one database!

    Oh, did i mention Catalyst now also supports PAR, ship all prereqs with your app, something Rails people can only dream of...
      They all have their strengths and weaknesses, so why not choose the best for the task at hand? Why not use multiple template engines, multiple orm's in the same application?

      Why write all of Catalyst in Perl, for that matter?

      Oh, wait.

Re^4: OT: Ruby On Rails - your thoughts?
by Fletch (Bishop) on Nov 17, 2005 at 20:31 UTC

    [ fields[ 1..4 ], fields[ 4..5 ], 0, 0 ].flatten should work in Ruby; passing a range to Array#[] returns the specified subarray.

    Update: And additionally it'd be more idiomatic to use do . . . end rather than {} around your blocks. Granted I don't think it makes a difference in this case but the later does bind more tightly than the former.

      [ fields[ 1..4 ], fields[ 4..5 ], 0, 0 ].flatten didn't work when I tried it, but I was probably doing something wrong. I'd like sth.execute() to take an array instead of requiring me to splat it, which would allow for sth.execute( [ ... ] ) vs. the annoying ary = [ ... ]; sth.execute( *ary ). Ideally, it would do something like:
      def execute( *args ) args.flatten .... end
      which would allow for sth.execute( fields[ 1..4 ], fields[ 4..5 ], 0, 0 ), but I'm sure there was a good reason to not do that. I haven't cared enough to find out what that reason was.

      And, yes, do..end is more idiomatic, but I'm not comfortable with it yet. I'm sure I'll be making the shift soon enough. :-)


      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?