SlideShare une entreprise Scribd logo
1  sur  25
Télécharger pour lire hors ligne
超実践 super
super practice for `super`
@kamina_zzz
湊谷 海斗
@kamina_zzz
2
食べログ
DevOps チーム 兼 データサイエンスチーム
● 各種バージョンアップやったり
● 内製のライブラリ書いたり
● 機械学習のシステム構築したり
● 日本酒飲んだり
● バンドやったり
minatoya kaito
きほん
3
basic usages
super のきほん class Super
def hello
puts 'Super: Hello World!'
end
end
class Sub < Super
def hello
super
end
end
Sub.new.hello
#=> Super: Hello World!
4
スーパークラスの
同名 method を探索
→ 実行
super のきほん
class Super
def hello
puts 'Super: Hello World!'
end
end
module Mod
def hello
puts 'Mod: Hello World from mod.'
end
end
class Sub < Super
include Mod
def hello
super
end
end
Sub.new.hello
#=> Mod: Hello World from mod.
5
正しくは:
継承上位の
同名 method を探索
→ 実行
super のきほん
class Ultra
def hello
puts 'Ultra: Hello World from Ultra.'
end
end
class Super < Ultra
end
class Sub < Super
def hello
super
end
end
Sub.new.hello
#=> Ultra: Hello World from Ultra.
6
正しくは:
継承上位の
同名 method を探索
→ 実行
super class Super
def hello(*args)
puts "Super: Hello #{args.join(',')}!"
end
end
class Sub < Super
def hello(*args)
super
end
end
Sub.new.hello('a', 'b', 'c')
#=> Super: Hello a,b,c!
7
引数の渡し方
● そのまま
● 無し
● 独自に設定
super() class Super
def hello(*args)
puts "Super: Hello #{args.join(',')}!"
end
end
class Sub < Super
def hello(*args)
super()
end
end
Sub.new.hello('a', 'b', 'c')
#=> Super: Hello !
8
引数の渡し方
● そのまま
● 無し
● 独自に設定
super(arg1, arg2) class Super
def hello(*args)
puts "Super: Hello #{args.join(',')}!"
end
end
class Sub < Super
def hello(*args)
super('Japan', 'JP', 'ja')
end
end
Sub.new.hello('a', 'b', 'c')
#=> Super: Hello Japan,JP,ja!
9
引数の渡し方
● そのまま
● 無し
● 独自に設定
パッチ
特定の method の
一部だけ変更したい
まさか ruby -v < 2.0 ってことは
ないですよね…?
class Target
def hello
puts "Hello World!"
end
end
module Japan
def hello
puts "Hello Japan!"
super
end
end
Target.prepend Japan
Target.new.hello
#=> Hello Japan!
#=> Hello World!
10
実践
11
practices
こんなときどうする?
12
# 動的に定義されるメソッドにパッチを当てたい
● クラスメソッドで指定した引数を元にメソッドを定義する機構があるとする
● そのメソッドの仕様を自分好みにカスタマイズしたい
動的に定義されるメソッドに
パッチを当てたい
こんな状況があったとして
この foo= にパッチを
あてたい
$attrs = [:foo, :bar]
class MyClass
attr_writer *$attrs
end
obj = MyClass.new
obj.foo = 'test'
13
やってみる
方針1:
同名のmethod を
define_method して、
その中で super を呼ぶ
$attrs = [:foo, :bar]
class MyClass
attr_writer *$attrs
end
module MyPatch
$attrs.each do |attr|
define_method("#{attr}=") do |val|
super(val)
puts 'this is patched!'
end
end
end
MyClass.prepend MyPatch
obj = MyClass.new
obj.foo = 'test'
14
やってみる
方針2:
module_eval して
同名 method を定義し、
その中で super を呼ぶ
$attrs = [:foo, :bar]
class MyClass
attr_writer *$attrs
end
module MyPatch
$attrs.each do |attr|
module_eval <<~EVAL, __FILE__, __LINE__ + 1
def #{attr}=(val)
super
puts "this is patched!"
end
EVAL
end
end
MyClass.prepend MyPatch
obj = MyClass.new
obj.foo = 'test'
15
※ module_eval == class_eval
define_method vs module_eval
16
pros/cons
17
- define_method module_eval
pros ● 行数がちょっと少なくて済む
● 例外時の見え方がわかりやすい
● 移植しやすい
cons
● super に渡す全引数を書かなきゃい
けない
● 人によっては(?)読みづらい
super の引数
`block (2 levels) in <module:MyPatch>': implicit argument passing of super from method defined by
define_method() is not supported. Specify all arguments explicitly. (RuntimeError)
18
module MyPatch
$attrs.each do |attr|
define_method("#{attr}=") do |val|
super
puts 'this is patched!'
end
end
end
パッチ部分をこのように書くと
怒られてしまう
super の引数
`block (2 levels) in <module:MyPatch>': implicit argument passing of super
from method defined by define_method() is not supported. Specify all
arguments explicitly. (RuntimeError)
19
define_method で定義された method の中では
super に暗黙的に引数を渡すことはサポートされてないよ。
だから明示的にすべての引数を書いて渡してね。
ko1 氏曰く「どーしても実装出来なかったからです.誰か,実装方法を教えてください. (原文ママ)」とのこと。
http://www.atdot.net/~ko1/diary/200806.html#d14
Exception の例
20
module MyPatch
$attrs.each do |attr|
define_method("#{attr}=") do |val|
super(val)
raise 'ERROR!!!'
end
end
end
define_method の場合
Traceback (most recent call last):
1: from tmp.rb:17:in `<main>'
tmp.rb:10:in `block (2 levels) in <module:MyPatch>': ERROR!!! (RuntimeError)
Exception の例
21
module MyPatch
$attrs.each do |attr|
module_eval <<~EVAL, __FILE__, __LINE__ + 1
def #{attr}=(val)
super
raise 'ERROR!!!'
end
EVAL
end
end
module_eval の場合
Traceback (most recent call last):
1: from tmp.rb:19:in `<main>'
tmp.rb:11:in `foo=': ERROR!!! (RuntimeError)
Exception の例
22
Traceback (most recent call last):
1: from tmp.rb:19:in `<main>'
tmp.rb:11:in `foo=': ERROR!!! (RuntimeError)
Traceback (most recent call last):
1: from tmp.rb:17:in `<main>'
tmp.rb:10:in `block (2 levels) in <module:MyPatch>': ERROR!!! (RuntimeError)
eval 系 method の第2, 第3 引数をちゃんとセットしておけば
例外が起きた method が明確
まとめ
● super にもいろいろあるので正しく使っていこう
● パッチを作るときは super + eval + prepend が良い感じ
23
おしまい
24
We're hiring!
25
@kamina_zzz
reply or DM =>

Contenu connexe

Tendances

Black jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとして
Black jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとしてBlack jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとして
Black jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとして
Shinichi Hirauchi
 
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
Shinichi Hirauchi
 
Itcamp長崎2012 capistrano
Itcamp長崎2012 capistranoItcamp長崎2012 capistrano
Itcamp長崎2012 capistrano
kumachang_LL
 
Puppet Best Practices? at COOKPAD
Puppet Best Practices? at COOKPADPuppet Best Practices? at COOKPAD
Puppet Best Practices? at COOKPAD
Gosuke Miyashita
 
ChefとPuppetの比較
ChefとPuppetの比較ChefとPuppetの比較
ChefとPuppetの比較
Sugawara Genki
 

Tendances (20)

Ansible入門...?
Ansible入門...?Ansible入門...?
Ansible入門...?
 
EC-CUBE + PHPUnit で 実践テスト駆動開発
EC-CUBE + PHPUnit で 実践テスト駆動開発EC-CUBE + PHPUnit で 実践テスト駆動開発
EC-CUBE + PHPUnit で 実践テスト駆動開発
 
Black jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとして
Black jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとしてBlack jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとして
Black jumbodogの新機能(webapi)~自動テストにおけるsmtpモックとして
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
 
Mysql casial01
Mysql casial01Mysql casial01
Mysql casial01
 
Chef
ChefChef
Chef
 
MySQLのパフォーマンスの話
MySQLのパフォーマンスの話MySQLのパフォーマンスの話
MySQLのパフォーマンスの話
 
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
2012 osc北海道 セッション資料「blackjumbodog利用のすすめ」
 
Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)
 
2014/11/08 第3回 一撃サーバー構築シェルスクリプト勉強会(懇親会もあるよ!) 発表資料
2014/11/08 第3回 一撃サーバー構築シェルスクリプト勉強会(懇親会もあるよ!) 発表資料2014/11/08 第3回 一撃サーバー構築シェルスクリプト勉強会(懇親会もあるよ!) 発表資料
2014/11/08 第3回 一撃サーバー構築シェルスクリプト勉強会(懇親会もあるよ!) 発表資料
 
Itcamp長崎2012 capistrano
Itcamp長崎2012 capistranoItcamp長崎2012 capistrano
Itcamp長崎2012 capistrano
 
B lack jumbodog 運転と改造のすすめ
B lack jumbodog 運転と改造のすすめB lack jumbodog 運転と改造のすすめ
B lack jumbodog 運転と改造のすすめ
 
Symfony2 workshop-2
Symfony2 workshop-2Symfony2 workshop-2
Symfony2 workshop-2
 
Ruby build
Ruby buildRuby build
Ruby build
 
カジュアルにバックアップ - MySQL Casual Talks 福岡
カジュアルにバックアップ - MySQL Casual Talks 福岡カジュアルにバックアップ - MySQL Casual Talks 福岡
カジュアルにバックアップ - MySQL Casual Talks 福岡
 
Puppet Best Practices? at COOKPAD
Puppet Best Practices? at COOKPADPuppet Best Practices? at COOKPAD
Puppet Best Practices? at COOKPAD
 
initramfsについて
initramfsについてinitramfsについて
initramfsについて
 
ChefとPuppetの比較
ChefとPuppetの比較ChefとPuppetの比較
ChefとPuppetの比較
 
シェル入門
シェル入門シェル入門
シェル入門
 
当社のawsへの取組
当社のawsへの取組当社のawsへの取組
当社のawsへの取組
 

Similaire à ebisu.rb #19 超実践 super

20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
Masanori Kado
 
Perl 非同期プログラミング
Perl 非同期プログラミングPerl 非同期プログラミング
Perl 非同期プログラミング
lestrrat
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unit
higaki
 
Lightning introduction to CoffeeScript 20131005
Lightning introduction to CoffeeScript 20131005Lightning introduction to CoffeeScript 20131005
Lightning introduction to CoffeeScript 20131005
gotohayato
 
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
kenjis
 

Similaire à ebisu.rb #19 超実践 super (20)

20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
 
super super & sub sub の話
super super & sub sub の話super super & sub sub の話
super super & sub sub の話
 
MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
モダンmod_perl入門 #yapcasia
モダンmod_perl入門 #yapcasiaモダンmod_perl入門 #yapcasia
モダンmod_perl入門 #yapcasia
 
Perl 非同期プログラミング
Perl 非同期プログラミングPerl 非同期プログラミング
Perl 非同期プログラミング
 
10分でわかるFuelPHP @ 2011/12
10分でわかるFuelPHP @ 2011/1210分でわかるFuelPHP @ 2011/12
10分でわかるFuelPHP @ 2011/12
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unit
 
Lightning introduction to CoffeeScript 20131005
Lightning introduction to CoffeeScript 20131005Lightning introduction to CoffeeScript 20131005
Lightning introduction to CoffeeScript 20131005
 
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
 
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
 10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya 10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
 
Rails解説セミナー: Railsアプリケーションのデバッグ
Rails解説セミナー: RailsアプリケーションのデバッグRails解説セミナー: Railsアプリケーションのデバッグ
Rails解説セミナー: Railsアプリケーションのデバッグ
 
DevOpsのアプローチと クラウド/バーチャル環境/構成管理ツール のお話
DevOpsのアプローチと クラウド/バーチャル環境/構成管理ツール のお話DevOpsのアプローチと クラウド/バーチャル環境/構成管理ツール のお話
DevOpsのアプローチと クラウド/バーチャル環境/構成管理ツール のお話
 
第4回Magento Cafe Plus〜Rewriteと独自テーブル
第4回Magento Cafe Plus〜Rewriteと独自テーブル第4回Magento Cafe Plus〜Rewriteと独自テーブル
第4回Magento Cafe Plus〜Rewriteと独自テーブル
 
Development app-with-elixir
Development app-with-elixirDevelopment app-with-elixir
Development app-with-elixir
 
今日から使い始めるChef
今日から使い始めるChef今日から使い始めるChef
今日から使い始めるChef
 
クラスのインスタンス変数について
クラスのインスタンス変数についてクラスのインスタンス変数について
クラスのインスタンス変数について
 
Ruby on Rails 入門
Ruby on Rails 入門Ruby on Rails 入門
Ruby on Rails 入門
 
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 
named_scope more detail - WebCareer
named_scope more detail - WebCareernamed_scope more detail - WebCareer
named_scope more detail - WebCareer
 
CakePHP 1 to 2 Migration tips 100
CakePHP 1 to 2 Migration tips 100CakePHP 1 to 2 Migration tips 100
CakePHP 1 to 2 Migration tips 100
 

ebisu.rb #19 超実践 super