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

VideoMapper

registry object

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

↓ Fiber

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

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

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

sensible default

Registry pattern from book Patterns of Enterprise Application Architecture

173 for

★★

for loop is simply using the #each method

forの問題、eachはOK

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

countdown_from(4)
# >> 4
# >> 3
# >> 2
# >> 1
# >> I counted down from 1

nをコピーしない

174 Multiple Assignment

★★

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

みたいな書き方は削除する時とか考えると良くない

Rubyではswapが次で書ける

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
shuttle_new_videos
edit shuttle_new_videos
reload-method shuttle_new_videos

Typhoeus

176 Dotenv

★★

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

省略

Dotenv.load

one other Dotenv feature worth mentioning

Dotenv has special support for Rake

require "dotenv/tasks"

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

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