------ art_31815_30029556.1145765378256 Content-Type: multipart/alternative; boundary --- art_31816_14544355.1145765378256" ------ art_31816_14544355.1145765378256 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline I forgot, here's the test data in case anyone wants it. Michael Guterl On 4/23/06, Michael Guterl <mguterl / gmail.com> 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? > > 2. Are my uses of class_eval and instance_eval okay / is there a better > way? > > 3. I am using facets because I like the Dictionary (OrderedHash), but I'm > sure there are better ways to build the structure while preserving the field > order. I especially don't like the fact that I have to specify Dictionary[] > in the structure of the subclass. > > 4. Please comment on the code in general, I'm open to any kind of > criticism. > > I'm not sure if it's customary to attach the code in a file or post it in > the email. I apologize if I should have attached the code in a file. > > Michael Guterl > > ---------------------------------------------- > > require 'rubygems' > require 'facets' > require 'dictionary' > > class FixedLength > > def self.structure(ordered_hash) > > class_eval do > @@structure = ordered_hash > end > > keys = @@structure.keys > instance_eval do > attr_accessor *keys > end > > end > > # this entire method could probably be a lot cleaner > > def self.open(file_name) > class_eval do > data = IO.read(file_name) > records = [] > data.each_line do |line| > last_position = 0 > record = self.new > @@structure.each_pair do |name, length| > record.instance_variable_set( "@#{name.to_s}", line.slice(last_position, > length.to_i).strip) > last_position += length.to_i > end > records << record > end > return records > end > end > > end > > class InputStructure < FixedLength > > # I'd like to clean this up, either removing the need for Dictionary[] > and the separation by commas > # or with something like this > # column.add :id, 10 > # column.add :phone, 10 > # column.add :first_name, 25 > # etc. I'd love to hear some suggestions. > > structure Dictionary[ :id , 10, > :phone , 10, > :first_name , 25, :middle_name , 1, :last_name , 25, > :address , 30, > :city , 25, > :state , 2, > :zip , 5, :zip4 , 4 ] > > end > > require 'test/unit' > > class InputStructureTest < Test::Unit::TestCase > > def setup > @records = InputStructure.open('fixed_data.txt') > end > > def test_first > record = @records.first > assert_equal "1", record.id > assert_equal "1234567890", record.phone > assert_equal "SOME RANDOM", record.first_name > assert_equal "", record.middle_name > assert_equal "PERSON", record.last_name > assert_equal "1234 SOME RANDOM STREET", record.address > assert_equal "RANDOM CITY", record.city > assert_equal "OH", record.state > assert_equal "45219", record.zip > assert_equal "", record.zip4 > end > > end > > ------ art_31816_14544355.1145765378256 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline I forgot, here's the test data in case anyone wants it.<br><br>Michael Guterl<br><br><div><span class="gmail_quote">On 4/23/06, <b class="gmail_sendername">Michael Guterl</b> <<a href="mailto:mguterl / gmail.com">mguterl / gmail.com </a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div style="direction: ltr;">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: <br> <br>1. Does the syntax appear to be in line with the community standards?<br><br>2. Are my uses of class_eval and instance_eval okay / is there a better way?<br><br>3. I am using facets because I like the Dictionary (OrderedHash), but I'm sure there are better ways to build the structure while preserving the field order. I especially don't like the fact that I have to specify Dictionary[] in the structure of the subclass. <br><br>4. Please comment on the code in general, I'm open to any kind of criticism.<br><br>I'm not sure if it's customary to attach the code in a file or post it in the email. I apologize if I should have attached the code in a file. <br><br>Michael Guterl<br><br>----------------------------------------------<br><br>require 'rubygems'<br>require 'facets'<br>require 'dictionary'<br><br>class FixedLength<br><br> def self.structure(ordered_hash)<br> <br> class_eval do<br> @@structure = ordered_hash<br> end<br> <br> keys = @@structure.keys<br> instance_eval do<br> attr_accessor *keys<br> end<br> <br> end<br> <br> # this entire method could probably be a lot cleaner <br><br> def self.open(file_name)<br> class_eval do<br> data = IO.read(file_name)<br> records = []<br> data.each_line do |line|<br> last_position = 0<br> record = self.new<br> @@structure.each_pair do |name, length|<br> record.instance_variable_set( "@#{name.to_s}", line.slice(last_position, length.to_i).strip)<br> last_position += length.to_i<br> end<br> records << record <br> end<br> return records<br> end<br> end<br><br>end<br><br>class InputStructure < FixedLength<br><br> # I'd like to clean this up, either removing the need for Dictionary[] and the separation by commas <br> # or with something like this<br> # column.add :id, 10<br> # column.add :phone, 10<br> # column.add :first_name, 25<br> # etc. I'd love to hear some suggestions.<br><br> structure Dictionary[ :id , 10, <br> :phone , 10, <br> :first_name , 25, :middle_name , 1, :last_name , 25, <br> :address , 30, <br> :city , 25, <br> :state , 2,br> :zip , 5, :zip4 , 4 ]<br><br>end<br><br>require 'test/unit' <br><br>class InputStructureTest < Test::Unit::TestCase<br><br> def setup<br> @records = InputStructure.open('fixed_data.txt')<br> end<br> <br> def test_first<br> record = @records.first<br> assert_equal "1", <a href="http://record.id" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">record.id</a><br> assert_equal "1234567890", record.phone<br> assert_equal "SOME RANDOM", record.first_name <br> assert_equal "", record.middle_name<br> assert_equal "PERSON", record.last_name<br> assert_equal "1234 SOME RANDOM STREET", record.address<br> assert_equal "RANDOM CITY", record.city<br> assert_equal "OH", record.state<br> assert_equal "45219", record.zip<br> assert_equal "", record.zip4<br> end<br> <br>end<br><br> </div></blockquote></div><br> ------ art_31816_14544355.1145765378256-- ------ art_31815_30029556.1145765378256 Content-Type: text/plain; name=fixed_data.txt; charset=us-ascii Content-Transfer-Encoding: 7bit X-Attachment-Id: f_emcv3dvs Content-Disposition: attachment; filename="fixed_data.txt" 1 1234567890SOME RANDOM PERSON 1234 SOME RANDOM STREET RANDOM CITY OH45219 ------ art_31815_30029556.1145765378256--