Here’s an implementation that uses our version of Array#each:
| class Array |
| def each |
| x = 0 |
| while x < self.length |
| yield self[x] |
| x += 1 |
| end |
| end |
| |
| def map |
| res = [] |
| each { |x| res << yield(x) } |
| res |
| end |
| end |
Here, we make use of the element that is yielded from each iteration of each and collect each element into res.
Here’s a possible implementation:
| class String |
| def each_word |
| x = 0 # => 0 |
| words = self.split |
| while x < words.length |
| yield words[x] |
| x += 1 |
| end |
| end |
| end |
Your final code should look something like this:
| class File |
| def self.open(name, mode, &block) |
| file = new(name, mode) |
| return file unless block_given? |
| yield(file) |
| ensure |
| file.close |
| end |
| end |
Does run require a block to be passed in?
Yes. There is no block_given?, and yield is called without any conditionals.
How is the return result of the block used?
The return result of the block is compared with :exit.
How could this code be called?
The key here is that the block passed has exactly one argument:
| Server.new.run do |session| |
| # do something with session |
| end |
The only change is to the Schema class:
| module ActiveRecord |
| class Schema |
| def self.define(version, &block) |
| instance_eval &block |
| end |
| |
| def self.create_table(table_name, options = {}, &block) |
| t = Table.new(table_name, options) |
| yield t |
| end |
| end |
| end |
Let’s take a look at the DSL again:
| 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 |
In the outermost block, (ActiveRecord::Schema.define do ... end), we instance_eval it in the context of the Schema class. That’s because the create_table method used in the block body is a class method.
The innermost block, create_table do ... end, takes a block with a single parameter. That parameter is a Table object. We can do yield t, or t.instance_eval &block would achieve the same effect.
18.225.234.24