Mercurial > repos > other > SevenLanguagesInSevenWeeks
view 1-Ruby/acts_as_csv_module-irb.output @ 35:22edfbf3b8bd
Add most of the self-study answers
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Wed, 06 Sep 2017 19:54:35 +0100 |
parents | 2ea3b5e9b41b |
children |
line wrap: on
line source
acts_as_csv_module.rb(main):001:0> #--- acts_as_csv_module.rb(main):002:0* # Excerpted from "Seven Languages in Seven Weeks", acts_as_csv_module.rb(main):003:0* # published by The Pragmatic Bookshelf. acts_as_csv_module.rb(main):004:0* # Copyrights apply to this code. It may not be used to create training material, acts_as_csv_module.rb(main):005:0* # courses, books, articles, and the like. Contact us if you are in doubt. acts_as_csv_module.rb(main):006:0* # We make no guarantees that this code is fit for any purpose. acts_as_csv_module.rb(main):007:0* # Visit http://www.pragmaticprogrammer.com/titles/btlang for more book information. acts_as_csv_module.rb(main):008:0* #--- acts_as_csv_module.rb(main):009:0* module ActsAsCsv acts_as_csv_module.rb(main):010:1> def self.included(base) acts_as_csv_module.rb(main):011:2> base.extend ClassMethods acts_as_csv_module.rb(main):012:2> # The book doesn't do this, but it is possible to add the methods acts_as_csv_module.rb(main):013:2* # without having the inheriting class call a second function to do it acts_as_csv_module.rb(main):014:2* base.acts_as_csv acts_as_csv_module.rb(main):015:2> end acts_as_csv_module.rb(main):016:1> acts_as_csv_module.rb(main):017:1* module ClassMethods acts_as_csv_module.rb(main):018:2> def acts_as_csv acts_as_csv_module.rb(main):019:3> include InstanceMethods acts_as_csv_module.rb(main):020:3> end acts_as_csv_module.rb(main):021:2> end acts_as_csv_module.rb(main):022:1> acts_as_csv_module.rb(main):023:1* module InstanceMethods acts_as_csv_module.rb(main):024:2> acts_as_csv_module.rb(main):025:2* def read acts_as_csv_module.rb(main):026:3> self.csv_contents = [] acts_as_csv_module.rb(main):027:3> filename = self.class.to_s.downcase + '.txt' acts_as_csv_module.rb(main):028:3> file = File.new(filename) acts_as_csv_module.rb(main):029:3> @headers = file.gets.chomp.split(', ') acts_as_csv_module.rb(main):030:3> acts_as_csv_module.rb(main):031:3* file.each do |row| acts_as_csv_module.rb(main):032:4* csv_row = CsvRow.new(headers, row.chomp.split(', ')) acts_as_csv_module.rb(main):033:4> @csv_contents << csv_row acts_as_csv_module.rb(main):034:4> end acts_as_csv_module.rb(main):035:3> end acts_as_csv_module.rb(main):036:2> acts_as_csv_module.rb(main):037:2* attr_accessor :headers, :csv_contents acts_as_csv_module.rb(main):038:2> def initialize acts_as_csv_module.rb(main):039:3> read acts_as_csv_module.rb(main):040:3> end acts_as_csv_module.rb(main):041:2> acts_as_csv_module.rb(main):042:2* def each() acts_as_csv_module.rb(main):043:3> self.csv_contents.each { |row| yield row } acts_as_csv_module.rb(main):044:3> end acts_as_csv_module.rb(main):045:2> end acts_as_csv_module.rb(main):046:1> end => :each acts_as_csv_module.rb(main):047:0> acts_as_csv_module.rb(main):048:0* class RubyCsv # no inheritance! You can mix it in acts_as_csv_module.rb(main):049:1> include ActsAsCsv acts_as_csv_module.rb(main):050:1> # Also, nothing to do beyond the "include" - it automatically defines the methods! acts_as_csv_module.rb(main):051:1* end => RubyCsv acts_as_csv_module.rb(main):052:0> acts_as_csv_module.rb(main):053:0* class CsvRow acts_as_csv_module.rb(main):054:1> attr_reader :values acts_as_csv_module.rb(main):055:1> acts_as_csv_module.rb(main):056:1* def initialize(headers, values) acts_as_csv_module.rb(main):057:2> @values = Hash[headers.zip(values)] acts_as_csv_module.rb(main):058:2> end acts_as_csv_module.rb(main):059:1> acts_as_csv_module.rb(main):060:1* def method_missing(methId, *args) acts_as_csv_module.rb(main):061:2> str = methId.id2name acts_as_csv_module.rb(main):062:2> if @values.key?(str) acts_as_csv_module.rb(main):063:3> return @values[str] acts_as_csv_module.rb(main):064:3> else acts_as_csv_module.rb(main):065:3* super.method_missing(methId) acts_as_csv_module.rb(main):066:3> end acts_as_csv_module.rb(main):067:2> end acts_as_csv_module.rb(main):068:1> end => :method_missing acts_as_csv_module.rb(main):069:0> acts_as_csv_module.rb(main):070:0* m = RubyCsv.new => #<RubyCsv:0x0000000212caf8 @csv_contents=[#<CsvRow:0x0000000212c558 @values={"first"=>"Yukihiro", "last"=>"Matsumoto", "country"=>"Japan"}>, #<CsvRow:0x0000000212c170 @values={"first"=>"Bruce", "last"=>"Tate", "country"=>"USA"}>], @headers=["first", "last", "country"]> acts_as_csv_module.rb(main):071:0> puts m.headers.inspect ["first", "last", "country"] => nil acts_as_csv_module.rb(main):072:0> puts m.csv_contents.inspect [#<CsvRow:0x0000000212c558 @values={"first"=>"Yukihiro", "last"=>"Matsumoto", "country"=>"Japan"}>, #<CsvRow:0x0000000212c170 @values={"first"=>"Bruce", "last"=>"Tate", "country"=>"USA"}>] => nil acts_as_csv_module.rb(main):073:0> # Use method_missing to implement heading-as-a-method acts_as_csv_module.rb(main):074:0* puts m.csv_contents[0].country Japan => nil acts_as_csv_module.rb(main):075:0> # And show that we still get normal failure behaviour acts_as_csv_module.rb(main):076:0* puts m.csv_contents[0].Country NoMethodError: undefined method `Country' for #<CsvRow:0x0000000212c558> from acts_as_csv_module.rb:65:in `method_missing' from acts_as_csv_module.rb:76 from /usr/bin/irb:11:in `<main>' acts_as_csv_module.rb(main):077:0> acts_as_csv_module.rb(main):078:0* acts_as_csv_module.rb(main):078:0>