Monday, September 18, 2006
Persistence for object oriented languages vs. programmer efficiency
I am about 4 months into a project using a very expensive object persistence mechanism (Franz Lisp AllegroCache) that almost automatically wraps Common Lisp CLOS classes for automatic persistence and B-Tree indexing of as many slots as you want to tag as indexed. As is sometimes is the case, here commercial software tools save time and effort. There is a very interesting open source project for Common Lisp (Elephant) that does something similar by using BerkleyDB or a relational database as the backend - it looks good, but it is not yet an out of the box solution.
For Java work, although I was once a fan of Hibernate, I try to use Prevayler instead: if you add new instance variables to the end of class definitions you can add to your object model without breaking your persistent storage - a neat trick, to be sure.
When it comes to the best programmer productivity using object relational mappers, I personally think that Ruby Rail's ActiveRecord wins hands down - with the slight cost that you design database schema instead of class models.
For Java work, although I was once a fan of Hibernate, I try to use Prevayler instead: if you add new instance variables to the end of class definitions you can add to your object model without breaking your persistent storage - a neat trick, to be sure.
When it comes to the best programmer productivity using object relational mappers, I personally think that Ruby Rail's ActiveRecord wins hands down - with the slight cost that you design database schema instead of class models.
Labels: Java, Lisp, object mapping, Ruby
Friday, June 30, 2006
Incredible what a few lines of Ruby code will do
Ruby, with great libraries like ActiveRecord and Ferret let you solve problems with just a few lines of code. I had 4 database tables that I wanted to index all fields of each row, and enable a plain text search that would quickly point me back to the table name and row index. The indexing takes about 20 lines of code and took less than 10 minutes to get working:
This would take a lot of code in Java, Common Lisp, etc. Unless my customers specifically ask me to use another programming language, I just about always use Ruby now.
class CreateIndex
def initialize
@index = Ferret::Index::Index.new(:path => './search_index')
ActiveRecord::Base.establish_connection(
:adapter => 'postgresql',
:host => 'localhost',
:username => 'postgres',
:database => 'test_database')
process_class(Item)
process_class(Plan)
process_class(Procedure)
process_class(Visit)
@index.close
end
def process_class the_class
the_class.find_all.each {|obj|
doc1 = Document.new
doc1 << Field.new("text", obj.attributes.values.join(' '), Field::Store::YES, Field::Index::TOKENIZED)
doc1 << Field.new("class", the_class.to_s, Field::Store::YES, Field::Index::NO)
doc1 << Field.new("id", obj.id.to_s, Field::Store::YES, Field::Index::NO)
@index << doc1
}
end
end
Labels: object mapping, Ruby
Friday, June 23, 2006
More work combining Ruby and Common Lisp
I am doing a lot of coding using both Lisp and Ruby for my current project. I am finding interop between the languages to be especially easy because of the dynamic nature of both languages. When I use REST style calls I can dynamically create classes and instances just from the XML so changing classes in one language does not break code in the other.
Labels: Lisp, object mapping, Ruby
Saturday, June 17, 2006
Meta object protocol in Lisp and Ruby
One thing that I like about Common Lisp and Ruby is the ability to examine class definitions, etc. at runtime. I have several model classes in a Common Lisp application and I want to implement a web services API for my application that in some cases returns model objects to the requester.
I wrote a very short utility function today that takes any class instance looks up all of the slot names, and then gets the slot values. I output to an XML stream.
I don't have to manually change any code to marshall any of my classes to XML if I change the model class definitions.
I wrote a very short utility function today that takes any class instance looks up all of the slot names, and then gets the slot values. I output to an XML stream.
I don't have to manually change any code to marshall any of my classes to XML if I change the model class definitions.
Labels: Lisp, object mapping, Ruby
Friday, June 09, 2006
Saving time with Ruby and ActiveRecord
I am working on a project that has many disparate data sources, and before I can do the interesting AI part everything needs to be normalized into our object models. Usually, this would be a mountain of work, but I am finding that using Ruby scripts with the ActiveRecord library is saving lots of time. I am basically taking advantage of both the dynamic nature of Ruby and the dynamic ORM functionality of ActiveRecord to cut the amount of required code (compared to say Java) by a large amount.
Ruby on Rails has a deserved reputation for saving time on web application development, but you should really consider ActiveRecord a separate part of Rails that can be used standalone.
Ruby on Rails has a deserved reputation for saving time on web application development, but you should really consider ActiveRecord a separate part of Rails that can be used standalone.
Labels: object mapping, Ruby
Thursday, May 25, 2006
Interesting product: AllegroCache
I have been evaluating AllegroCache for a customer for one of their tasks. AllegroCache provides a metaclass that allows programmers to make CLOS classes persistent with very little work. AllegroCache is similar to Berkeley DB B-Tree but is implemented in Lisp and scales to very large problem sets. Individual class slots can be tagged to be indexed for fast lookup and search.
It is possible to write something like AllegroCache in a dynamic language like Common Lisp. The obvious idea for me is: do this in other dynamic languages like Ruby! The job would be easier in Ruby assuming that Ruby is already linked with the open source licensed Berkeley DB libraries. I already use Ruby's DBM disk-based hash libraries a lot, but being able to search on multiple class attributes would be great. AllegroCache supports great query functionality, so implementing something close to AllegroCache's functionality in Ruby would probably be at least a couple month task. One problem with this idea is that Franz Lisp with AllegroCache is really targeted at high end, high performance systems - Ruby is simply much slower that natively compiled Common Lisp, so an AllegroCache port to Ruby would not be as performant.
It is possible to write something like AllegroCache in a dynamic language like Common Lisp. The obvious idea for me is: do this in other dynamic languages like Ruby! The job would be easier in Ruby assuming that Ruby is already linked with the open source licensed Berkeley DB libraries. I already use Ruby's DBM disk-based hash libraries a lot, but being able to search on multiple class attributes would be great. AllegroCache supports great query functionality, so implementing something close to AllegroCache's functionality in Ruby would probably be at least a couple month task. One problem with this idea is that Franz Lisp with AllegroCache is really targeted at high end, high performance systems - Ruby is simply much slower that natively compiled Common Lisp, so an AllegroCache port to Ruby would not be as performant.
Labels: object mapping
Subscribe to Posts [Atom]
