Time to put on that thinking cap and flex that gray matter. Remember, in order to really understand the material, you should attempt to complete the following exercises. None of them should take too long, and you have my permission to peek at the solutions if you get stuck.
Implement Array#map using Array#each:
| %w(look ma no for loops).map do |x| |
| x.upcase |
| end |
This should return ["LOOK", "MA", "NO", "FOR", "LOOPS"].
Implement String#each_word:
| "Nothing lasts forever but cold November Rain".each_word do |x| |
| puts x |
| end |
This should output:
| Nothing |
| lasts |
| forever |
| but |
| cold |
| November |
| Rain |
It’s your turn to implement File.open. Start off with the Ruby documentation. The key here is to understand where to put pre- and post-processing code, where to put yield, and ensure that resources are cleared up.
Here’s some real-world code adapted from the Ruby Redis library:[5]
| module Redis |
| class Server |
| # ... more code ... |
| |
| def run |
| loop do |
| session = @server.accept |
| |
| begin |
| return if yield(session) == :exit |
| ensure |
| session.close |
| end |
| end |
| rescue => ex |
| $stderr.puts "Error running server: #{ex.message}" |
| $stderr.puts ex.backtrace |
| ensure |
| @server.close |
| end |
| |
| # ... more code ... |
| end |
| end |
Notice the similarities to the File.open example. Does run require a block to be passed in? How is the return result of the block used? How could this code be called?
Implementing the ActiveRecord DSL
Active Record is an object-relational mapper used in Rails, which connects objects, such as Micropost, to a database table. A migration in Active Record is a file that, when executed, makes changes to the database. Here’s an example of a migration in ActiveRecord:
| ActiveRecord::Schema.define(version: 20130315230445) do |
| create_table "microposts", force: true do |t| |
| t.string "content" |
| t.integer "user_id" |
| t.datetime "created_at" |
| t.datetime "updated_at" |
| end |
| end |
You don’t have to know how Active Record works. Your job is to implement the DSL. Here’s the full code, with placeholders for you to implement your solution:
| module ActiveRecord |
| class Schema |
| def self.define(version, &block) |
| # *** <code here> *** |
| end |
| def self.create_table(table_name, options = {}, &block) |
| t = Table.new(table_name, options) |
| # *** <code here> *** |
| end |
| end |
| |
| class Table |
| def initialize(name, options) |
| @name = name |
| @options = options |
| end |
| |
| def string(value) |
| puts "Creating column of type string named #{value}" |
| end |
| |
| def integer(value) |
| puts "Creating column of type integer named #{value}" |
| end |
| |
| def datetime(value) |
| puts "Creating column of type datetime named #{value}" |
| end |
| end |
| end |
| |
| ActiveRecord::Schema.define(version: 20130315230445) do |
| create_table "microposts", force: true do |t| |
| t.string "content" |
| t.integer "user_id" |
| t.datetime "created_at" |
| t.datetime "updated_at" |
| end |
| end |
If you’ve done everything right, you will see:
| Creating column of type string named content |
| Creating column of type integer named user_id |
| Creating column of type datetime named created_at |
| Creating column of type datetime named updated_at |
3.144.30.62