quattro_4 scribble

scribble 落書き (調べた事をただ落書きする)

RubyTapas #167 - #178

167 Debugging in Gems


  • System
  • User (~/.gem)
  • Version-specific
  • Gemset-specific
  • Project (vendor)

  • bundle show rake

  • bundle open rake
  • gem install gem-open
    • gem open rake

Revert gem

gem pristine rake

168 Enumerable Internals

Pat Shaughnessy

Investigate rb_block_call

gdb ruby
(gdb) b enum_all
=> breakpoint
(gdb) r all.rb
(gdb) b all_iter_i
(gdb) c
=> continue

ENUMFUNC, rb_yield, enum_yield

Book Ruby Under a Microscope

169 Caching Proxy

class CachedContentPostGateway
  def initialize(gateway, cache)
    @gateway = gateway
    @cache   = cache

  cache_key = ...
  @cache.fetch(cache_key) do
  @cache[cache_key] = 

I didn't have to change either EpisodeMapper or ContentPostGateway at all.

book Patterns of Enterprise Application Architecture

170 Hash Merge

headers.lines.reduce({}) do |result, line|

block passed to merge

result.merge(name.strip => value.strip) {
  |key, left, right|
  Array(left) + Array(right)

Rails reverse_merge (Useful to add default)

171 puts


"PUT String"

flatten array

load path of the current Ruby process

puts $:

172 Registry

EpisodeMapper again


registry object

def self.video_map
  @video_mapper ||= VideoMapper.new(wistia_gateway, id_map: id_map)
@video_map = options.fetch(:video_map) { RubyTapas.video_map }

↓ Fiber

def self.scope
  @scope ||= FiberScope.new

def self.scope=(new_scope)
  @scope = new_scope 

def self.video_map
  scope[:video_mapper] ||= VideoMapper.new(wistia_gateway, id_map: id_map)

sensible default

Registry pattern from book Patterns of Enterprise Application Architecture

173 for


for loop is simply using the #each method


def countdown_from(n)
  for n in n.downto(1)
    puts n
  puts "I counted down from #{n}"

# >> 4
# >> 3
# >> 2
# >> 1
# >> I counted down from 1


174 Multiple Assignment


@filter, @current_user, @topics_input = filter, current_user, topics



x, y = y, x
x                               # => 2
y                               # => 1

175 REPL-Driven Development


Read Eval Print Loop

video_suttle project

pry -I./lib -rpry-byebug -rvideo_shuttle

cd VideoShuttle
edit shuttle_new_videos
reload-method shuttle_new_videos


176 Dotenv


require 'dotenv'
Dotenv.load(File.expand_path("../.env",  __FILE__))



one other Dotenv feature worth mentioning

Dotenv has special support for Rake

require "dotenv/tasks"

task :my_task => :dotenv do
  # ...

177 Aliasing

TeenyMapper LazyProxy

  • method_missing
  • __get__
  • store
  • store_row
  • find
  • find_all
  • load

When we walk down to an author's stories, then pick the first story, then follow the association back up to the author, we get an object which looks in every way like the original author—except that it is a different instance

The name for this phenomenon is aliasing, and it's one of the most insidious sources of defects in code that talks to a database through some kind of ORM layer

The :inverse_of options give ActiveRecord the extra information it needs to avoid repeatedly fetching and aliasing the same record when following associations. However, this isn't a complete solution

178 Identity Map

class TeenyMapper
  # ...
  def initialize(id_map)
    @id_map = id_map

  def store(object)
    @id_map[[object.class, object.id]] = object
  • Identity Map Implementations
    • ActiveRecord (had an optional identity map, but unfortunately it was removed because of bugs)
    • DataMapper
    • Ruby Object Mapper (young)
    • Perpetuity (young)
    • Mongoid