|
[Ruby]
Annotations in Ruby
[
Aslak Hellesoy
]
A couple of days ago I wished there was a way to use annotations in Ruby. I'm writing a Ruby on Rails application that renders a lot of objects in HTML. Many of these objects are "editable" via the web interface, and in order to make it easier for the user, I wanted the web interface to have both an explanatory text and a HTML tooltip for each object's field. Because I like simple things I also like to keep things in one place (I don't want to maintain this metadata in a separate RHTML template). Ruby doesn't support annotations out of the box, so I opened up the Class class and added support for annotations. Now I can do:
require 'rscm/annotations' class EmailSender ann :description => "IP address of the mail server", :tip => "Use 'localhost' if you have a good box, sister!" attr_accessor :server end The class' annotations can then be accessed like this:
EmailSender.server[:description] # => "IP address of the mail server"It took the Java community forever to do stuff like this. First a couple of years of XDoclet, then JSR175. And tons of code too. In Ruby it's 1 hour's work and 25 lines of code. Go figure. For more info see http://rscm.rubyforge.org/classes/Class.html And oh, here's the code: class Class def ann(anns) @@anns ||= {} def self.method_missing(sym, *args) #:nodoc: @@anns[sym] end $attr_anns ||= {} $attr_anns.merge!(anns) end alias old_attr_reader attr_reader #:nodoc: def attr_reader(*syms) #:nodoc: syms.each do |sym| @@anns[sym] = $attr_anns end $attr_anns = nil old_attr_reader(*syms) end def attr_accessor(*syms) #:nodoc: attr_reader(*syms) attr_writer(*syms) end end ... and why does you crap show up on Javablogs? --John, February 25, 2005 07:02 AM
... because i had registered the wrong feed on javablogs (fixed now, only my java posts will show there from now). sorry for ruining your day. --Aslak Hellesoy, February 25, 2005 07:13 AM
Very interesting. I've been playing a lot with Javascript lately once I discovered it supported closures and, with Rhino anyways, was possible to port Groovy-like JVM extensions to it. Anyways, your post inspired me to see if annotations could be ported to Javascript and I discovered they could be, so thanks. :) --Don Brown, February 25, 2005 08:00 AM
Please don't be intimidated by ignorants like John. Javablogs is interesting because many technological discussions appear there, even if the main scope is java. I for one hope you and others will continue to publish these things to javablogs. so to John, please use the javablogs filters to ban blogs that you do not care for i do this with most non-english blogs), but otherwise STFU. --Morten Wilken, February 25, 2005 10:20 AM
Hear, hear, Morten. If some obnoxious twat fails to see how these things are related - he has little chance of "grokking" Java either. Let them go back to coding from manuals and googling for cut'n'paste snippets. --Oskari Kettunen, February 25, 2005 11:40 AM
Hmm. Besides ann implementation for Ruby, it looks like this particular usacase for annotations is wrong. Wouldn't it be more logical to implement Editable interface in all your editable objects and provide these values (or better keys for NLS properties) out there? There should be other advandages of such approach. --eu, February 25, 2005 12:55 PM
Eu: What's unlogical or wrong about my example? Are you suggesting it's better to introduce more complexity to get things "right", even if a low-fi solution works? I care more whether code is readable, simple and maintainable than whether it's following a pattern or a spec. If you evaluate a technical approach with a Java mindset (which you seem to be doing - Ruby doesn't have interfaces), most code written in other languages will seem "wrong". --Aslak Hellesoy, February 25, 2005 04:09 PM
Cool feature! I agree it would be nice to have it use a key pointing to a language resource file for the particular use case but nicely done! --Todd Huss, February 25, 2005 06:40 PM
Ah, I see what eu meant now - I didn't get the TLA for NLS at first (National Language Support). -Sure, doing some NLS'ish on top would be trivial. But I'd keep that outside the annotations implementation in Class. --Aslak Hellesoy, February 25, 2005 07:55 PM
Here is an example of how to render an object into a n HTML table from Rails (put this code in your application.rb) http://rafb.net/paste/results/864R1421.html --Aslak Hellesoy, February 26, 2005 06:55 AM
Well, it's a hack. I'd rather try to lobby for a standard support from Ruby language. Meta information is always handy and the ruby community is very keen on accepting crazy ideas. --hammett, March 2, 2005 03:41 AM
1 full hour? You could have said the truth (10 minutes at most, if you're quite sloppy at meta-programming), I don't think these javaheads would bite you for that. They sort of managed to put up with DHH after all... Besides, the implementation is flawed. You should have used class instance variables. You could make it at least thread-safe with a Class granularity very easily. But I can understand that most railers won't care about that. --blergh, March 9, 2005 05:55 PM
You don't need to use global variables (bad smell): http://rafb.net/paste/results/Ym4BCH33.html --Kent, March 9, 2005 11:12 PM
Or even better: --Kent, March 10, 2005 01:05 AM
Post a comment
|