views:

72

answers:

2

It is said that Ruby is a metaprogramming language. I wonder if the first 3 lines can be made less verbose using metaprogramming?

RUBY_VERSION ||= "unknown version"
RUBY_PATCHLEVEL ||= "unknown patchlevel"
RUBY_PLATFORM ||= "unknown platform"

print "Ruby ", RUBY_VERSION, " patch ", RUBY_PATCHLEVEL, " on ", RUBY_PLATFORM
+2  A: 

This does the job:

%w{version patchlevel platform}.each{|v| eval "RUBY_#{v.upcase} ||= 'unknown #{v}'"}

but I think it's opaque and unpleasant. I think your original version is much better. In particular, I think ||= with constants isn't great anyway (since constants shouldn't be dynamic), and that using eval with constants is not standard or therefore expected. Putting conditional assignment, constants and eval all together makes for a bad mix, in my opinion.

Peter
+1 for the explanation. I think the original version is better too.
Anurag
A: 

I think that you shouldn't change value of constants. Instead try this:

puts "Ruby #{RUBY_VERSION || 'unknown version'}" # ...

Also, using Rails goodies, you could improve Peter's solution by calling

"RUBY_#{v}".constantize

instead of dirty eval ;-)

samuil