From: Michael Guterl Date: 2006-04-23T22:09:23+09:00 Subject: Re: Metaprogramming is fun! ------=_Part_33260_6466884.1145797759995 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Thanks David! I removed the evals, cleaned up self.open, and ran my tests and everything works. I really like the fact that I don't have to use the last_position variable and I can use String#slice! to incrementally chop it down. Any time you feel like reflecting on the need for class variables, my ears are open. Thanks again! Michael Guterl On 4/23/06, dblack@wobblini.net wrote: > > Hi -- > > On Sun, 23 Apr 2006, Michael Guterl wrote: > > > I finally decided to dive in and give metaprogramming in Ruby a > shot. I'm > > not sure that my example is exactly practical, but it seemed useful at > the > > time. There's a few areas I would like to hear others suggestions on: > > > > 1. Does the syntax appear to be in line with the community standards? > > You're indenting one space instead of two on the first indent, but > generally it looks good. > > > 2. Are my uses of class_eval and instance_eval okay / is there a better > way? > > See below. > > > require 'rubygems' > > require 'facets' > > require 'dictionary' > > > > class FixedLength > > > > def self.structure(ordered_hash) > > > > class_eval do > > @@structure =3D ordered_hash > > end > > > > keys =3D @@structure.keys > > instance_eval do > > attr_accessor *keys > > end > > I'm not sure why you're using all these *_eval calls. Try this: > > def self.structure(ordered_hash) > @@structure =3D ordered_hash > attr_accessor *@@structure.keys > end > > > end > > > > # this entire method could probably be a lot cleaner > > > > def self.open(file_name) > > class_eval do > > I haven't tested it but I don't see any reason for that one either. > > > data =3D IO.read(file_name) > > records =3D [] > > data.each_line do |line| > > last_position =3D 0 > > record =3D self.new > > @@structure.each_pair do |name, length| > > record.instance_variable_set( "@#{name.to_s}", > > The #{} thing does an automatic to_s. Also, since you've gone to the > trouble of creating accessors, why not do: > > record.send("#{name}=3D"), line.slice... > > > line.slice(last_position, > > length.to_i).strip) > > last_position +=3D length.to_i > > end > > records << record > > end > > return records > > end > > end > > > > end > > You could tighten that method up a bit. Here's an untested rewrite; > see if this is of any use: > > def self.open(file_name) > records =3D [] > File.open(file_name) do |fh| > fh.each_line do |line| > record =3D new > @@structure.each do |name,len| > record.send("#{name}=3D", line.slice!(0,len)) > end > records << record > end > end > return records > end > > (I'll save my reflections on the likelihood of class variables being > necessary for another time :-) > > > David > > -- > David A. Black (dblack@wobblini.net) > Ruby Power and Light, LLC (http://www.rubypowerandlight.com) > > "Ruby for Rails" PDF now on sale! http://www.manning.com/black > Paper version coming in early May! > > ------=_Part_33260_6466884.1145797759995--