SlideShare uma empresa Scribd logo
1 de 24
Baixar para ler offline
演算子オーバーライドを
DSLに活用する
makoto kuwata
http://www.kuwata-lab.com/
FukuokaRubyKaigi01
1
copyright© 2008 kuwata-lab.com all rights reserved
基本アイデア
‣ 演算結果として構文木を返す
‣ "構文解析" ではなく "評価"
x + y * 2
+
x
y 2
*
構文解析(parse)
評価(evaluate)
2
サンプルコード
3
copyright© 2008 kuwata-lab.com all rights reserved
サンプルコード: クラス関係
class Node
...
end
class Expression < Node
...
end
class Variable < Node
...
end
構文木要素
式
変数
4
copyright© 2008 kuwata-lab.com all rights reserved
サンプルコード: Nodeクラス
class Node
def +(arg)
return Expression.new(:'+', self, arg)
end
def *(arg)
return Expression.new(:'*', self, arg)
end
....
end
演算結果として式を返す
5
copyright© 2008 kuwata-lab.com all rights reserved
サンプルコード: Expressionクラス
class Expression < Node
def initialize(token, left, right)
@token = token
@left = left
@right = right
end
attr_accessor :token, :left, :right
end
トークンと、
左右の Node を保持
6
copyright© 2008 kuwata-lab.com all rights reserved
サンプルコード: Variableクラス
class Variable < Node
def initialize(name)
@name = name
end
attr_accessor :name
end
変数名を保持
7
copyright© 2008 kuwata-lab.com all rights reserved
サンプルコード: 実行例
x = Variable.new('x')
y = Variable.new('y')
x + y * 2
#=> Expression.new(:'+',
Variable.new('x'),
Expression.new(:'*',
Variable.new('y'),
1
)
)
+
x
y 2
*
...構文木をさらに変換
'+' より '*' の
ほうが強い
8
応用例
9
copyright© 2008 kuwata-lab.com all rights reserved
応用例:Ruby式をSQLへ
# Ruby #=> SQL
x == 10 #=> x = 10
x == nil #=> x is null
x ** 3 #=> power(x, 3)
Ruby式 構文木 SQL
参考: Operast (http://github.com/kwatch/operast/)
10
copyright© 2008 kuwata-lab.com all rights reserved
応用例:Ruby式をSQLへ
# Ruby #=> SQL
x > Date.new #=> x > '2008-12-06'
x =~ '%pattern%' #=> x like '%pattern%'
x.in? [1,4,7] #=> x in (1,4,7)
x.in? 10..20 #=> x between 10 and 20
参考: Operast (http://github.com/kwatch/operast/)
11
copyright© 2008 kuwata-lab.com all rights reserved
応用例:O/R Mapper の Model
class User
set_table_name('users')
@name = Variable.new('name')
def self.name; return @name; end
# or class <<self; attr_reader :name; end
end
User.name == nil #=> users.name is null
12
問題点、その他
13
copyright© 2008 kuwata-lab.com all rights reserved
言語の必要条件
‣ 演算子がオーバーライドできること
• Ruby
• Python
• C++ (演算子オーバーロード)
‣ 型がないこと or 型が変更できること
• 「==」の戻り値の型が boolean に固定されている
と、実現不可能
14
copyright© 2008 kuwata-lab.com all rights reserved
問題点:オーバーライド不可
‣ オーバーライドできない演算子がある
• 例:Ruby1.8 では、「!=」は 「==の否定」に固定
‣ 解決策:
• 他の演算子で代用(「^」「<=>」など)
• 「x.not」や「x.ne」(not equal) を提供
x.not == 1 #=> x != 1
15
copyright© 2008 kuwata-lab.com all rights reserved
問題点:&& と ||
‣ 「&&」と「||」はオーバーライドできない
• 評価のショートカットがあるため
‣ 解決策:
• メソッドで代用(「.and」「.or」)
• bit 演算子で代用(ただし演算子の優先順位に注意)
(x == 1) & (y == 2) #=> x = 1 and y = 2
16
copyright© 2008 kuwata-lab.com all rights reserved
問題点:1 + x
‣ 「x + 1」は OK だが「1 + x」は NG
‣ 解決策:一時的に Integer#+ を override
def sandbox
begin
Integer#+ に alias 名をつけて退避
Integer#+ をオーバーライド
yield 
ensure
Integer#+ をもとに戻す
end
17
copyright© 2008 kuwata-lab.com all rights reserved
問題点:動作速度
‣ 動作速度は、たぶん遅い
• 自作 O/R Mapper で評価中
‣ 解決策:
• なさそう?
• キャッシュもできない(or 逆に遅くなる)
• 最高速である必要はない
(気にならない程度の遅さならよしとする)
18
まとめ
19
copyright© 2008 kuwata-lab.com all rights reserved
まとめ
‣ 演算子をオーバーライドして構文木を返す
•「構文解析」ではなく「評価」
•Ruby の式をそのまま使う → DSLで使いやすい
‣ アイデア次第で面白い使い方ができるかも
20
copyright© 2008 kuwata-lab.com all rights reserved
参考
‣ SQLAlchemy (Python)
• http://www.sqlalchemy.org/
‣ Sequel (Ruby)
• http://sequel.rubyforge.org/
‣ RSpec (Ruby)
• http://rspec.info/
‣ Operast (Ruby)
• http://github.com/kwatch/operast/
21
one more thing...
22
copyright© 2008 kuwata-lab.com all rights reserved
こんな面倒なこと、本当に必要?
‣ Lispなら、同じことが「'」だけでできる
‣ 言語として必要な機能を Ruby が提供して
いないだけでは?
(+ x (* y 2) ) ;; 式が計算される
'(+ x (* y 2) ) ;; 式の構文木が返される
Lisp最強
23
thank you
24

Mais conteúdo relacionado

Mais procurados

From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To ClojureKent Ohashi
 
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化Lintaro Ina
 
Introduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshellIntroduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshellbitter_fox
 
Xtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うXtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うTatsumi Naganuma
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1Susisu
 
Shibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R についてShibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R についてtnoda
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門Makoto Fukuhara
 
【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream APIdcomsolution
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLispKent Ohashi
 
D言語会議#1
D言語会議#1D言語会議#1
D言語会議#19rnsr
 
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallなおき きしだ
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPIAkihiro Ikezoe
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)x1 ichi
 
Java8 lambdas chapter1_2
Java8 lambdas chapter1_2Java8 lambdas chapter1_2
Java8 lambdas chapter1_2yo0824
 
Java8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみるJava8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみるShinya Mochida
 

Mais procurados (20)

From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
 
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
 
Introduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshellIntroduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshell
 
Xtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うXtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使う
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
 
Shibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R についてShibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R について
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門
 
【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLisp
 
R spec勉強会
R spec勉強会R spec勉強会
R spec勉強会
 
D言語会議#1
D言語会議#1D言語会議#1
D言語会議#1
 
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
 
Clojure
ClojureClojure
Clojure
 
Functional Way
Functional WayFunctional Way
Functional Way
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)
 
Java8 lambdas chapter1_2
Java8 lambdas chapter1_2Java8 lambdas chapter1_2
Java8 lambdas chapter1_2
 
Java8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみるJava8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみる
 

Destaque

Benchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for PerformanceBenchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for Performancekwatch
 
HTMLデザインを崩さないテンプレートエンジンの作り方パート2
HTMLデザインを崩さないテンプレートエンジンの作り方パート2HTMLデザインを崩さないテンプレートエンジンの作り方パート2
HTMLデザインを崩さないテンプレートエンジンの作り方パート2kwatch
 
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -kwatch
 
PHPer100人にPythonを教えてみた
PHPer100人にPythonを教えてみたPHPer100人にPythonを教えてみた
PHPer100人にPythonを教えてみたkwatch
 
ビュー層におけるキャッシュの問題点とその解決策
ビュー層におけるキャッシュの問題点とその解決策ビュー層におけるキャッシュの問題点とその解決策
ビュー層におけるキャッシュの問題点とその解決策kwatch
 
Tenjin - the fastest template engine in the world
Tenjin - the fastest template engine in the worldTenjin - the fastest template engine in the world
Tenjin - the fastest template engine in the worldkwatch
 
デザイナーとの協業を本気で考える
デザイナーとの協業を本気で考えるデザイナーとの協業を本気で考える
デザイナーとの協業を本気で考えるkwatch
 
HTMLデザインを崩さないテンプレートエンジンの作り方
HTMLデザインを崩さないテンプレートエンジンの作り方HTMLデザインを崩さないテンプレートエンジンの作り方
HTMLデザインを崩さないテンプレートエンジンの作り方kwatch
 

Destaque (8)

Benchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for PerformanceBenchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for Performance
 
HTMLデザインを崩さないテンプレートエンジンの作り方パート2
HTMLデザインを崩さないテンプレートエンジンの作り方パート2HTMLデザインを崩さないテンプレートエンジンの作り方パート2
HTMLデザインを崩さないテンプレートエンジンの作り方パート2
 
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
 
PHPer100人にPythonを教えてみた
PHPer100人にPythonを教えてみたPHPer100人にPythonを教えてみた
PHPer100人にPythonを教えてみた
 
ビュー層におけるキャッシュの問題点とその解決策
ビュー層におけるキャッシュの問題点とその解決策ビュー層におけるキャッシュの問題点とその解決策
ビュー層におけるキャッシュの問題点とその解決策
 
Tenjin - the fastest template engine in the world
Tenjin - the fastest template engine in the worldTenjin - the fastest template engine in the world
Tenjin - the fastest template engine in the world
 
デザイナーとの協業を本気で考える
デザイナーとの協業を本気で考えるデザイナーとの協業を本気で考える
デザイナーとの協業を本気で考える
 
HTMLデザインを崩さないテンプレートエンジンの作り方
HTMLデザインを崩さないテンプレートエンジンの作り方HTMLデザインを崩さないテンプレートエンジンの作り方
HTMLデザインを崩さないテンプレートエンジンの作り方
 

Semelhante a 演算子オーバーライドをDSLに活用する

JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタートShumpei Shiraishi
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogrammingMasanori Kado
 
PHPフレームワーク入門
PHPフレームワーク入門PHPフレームワーク入門
PHPフレームワーク入門Sho A
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patternsnekop
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„和弘 井之上
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッドKohsuke Yuasa
 
Serverside ES6@Livesense technight
Serverside ES6@Livesense technightServerside ES6@Livesense technight
Serverside ES6@Livesense technightSeiji Takahashi
 
Java8から17へ
Java8から17へJava8から17へ
Java8から17へonozaty
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜ericsagnes
 
実録!Railsのはまりポイント10選
実録!Railsのはまりポイント10選実録!Railsのはまりポイント10選
実録!Railsのはまりポイント10選Drecom Co., Ltd.
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)Yoshifumi Yamaguchi
 
第一回社内 Scala 勉強会(一部抜粋)
第一回社内 Scala 勉強会(一部抜粋)第一回社内 Scala 勉強会(一部抜粋)
第一回社内 Scala 勉強会(一部抜粋)lyrical_logical
 
SpringOne 2016 報告 Reactive APIの設計・実装・使用
SpringOne 2016 報告 Reactive APIの設計・実装・使用SpringOne 2016 報告 Reactive APIの設計・実装・使用
SpringOne 2016 報告 Reactive APIの設計・実装・使用Takuya Iwatsuka
 

Semelhante a 演算子オーバーライドをDSLに活用する (20)

JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 
Lithium Labo #1
Lithium Labo #1Lithium Labo #1
Lithium Labo #1
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
 
PHPフレームワーク入門
PHPフレームワーク入門PHPフレームワーク入門
PHPフレームワーク入門
 
Tdd
TddTdd
Tdd
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patterns
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
 
MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
 
Serverside ES6@Livesense technight
Serverside ES6@Livesense technightServerside ES6@Livesense technight
Serverside ES6@Livesense technight
 
Java8から17へ
Java8から17へJava8から17へ
Java8から17へ
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜
 
実録!Railsのはまりポイント10選
実録!Railsのはまりポイント10選実録!Railsのはまりポイント10選
実録!Railsのはまりポイント10選
 
Ruby 2.5
Ruby 2.5Ruby 2.5
Ruby 2.5
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)
 
qmake入門
qmake入門qmake入門
qmake入門
 
第一回社内 Scala 勉強会(一部抜粋)
第一回社内 Scala 勉強会(一部抜粋)第一回社内 Scala 勉強会(一部抜粋)
第一回社内 Scala 勉強会(一部抜粋)
 
Aizu lt tokyo_luxion
Aizu lt tokyo_luxionAizu lt tokyo_luxion
Aizu lt tokyo_luxion
 
SpringOne 2016 報告 Reactive APIの設計・実装・使用
SpringOne 2016 報告 Reactive APIの設計・実装・使用SpringOne 2016 報告 Reactive APIの設計・実装・使用
SpringOne 2016 報告 Reactive APIの設計・実装・使用
 

Mais de kwatch

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Pythonkwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
なんでもID
なんでもIDなんでもID
なんでもIDkwatch
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方kwatch
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方kwatch
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?kwatch
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)kwatch
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するkwatch
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策kwatch
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurialkwatch
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -kwatch
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみたkwatch
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"kwatch
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラムkwatch
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンkwatch
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapperkwatch
 

Mais de kwatch (20)

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
なんでもID
なんでもIDなんでもID
なんでもID
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較する
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapper
 

Último

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 

Último (8)

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 

演算子オーバーライドをDSLに活用する

  • 2. copyright© 2008 kuwata-lab.com all rights reserved 基本アイデア ‣ 演算結果として構文木を返す ‣ "構文解析" ではなく "評価" x + y * 2 + x y 2 * 構文解析(parse) 評価(evaluate) 2
  • 4. copyright© 2008 kuwata-lab.com all rights reserved サンプルコード: クラス関係 class Node ... end class Expression < Node ... end class Variable < Node ... end 構文木要素 式 変数 4
  • 5. copyright© 2008 kuwata-lab.com all rights reserved サンプルコード: Nodeクラス class Node def +(arg) return Expression.new(:'+', self, arg) end def *(arg) return Expression.new(:'*', self, arg) end .... end 演算結果として式を返す 5
  • 6. copyright© 2008 kuwata-lab.com all rights reserved サンプルコード: Expressionクラス class Expression < Node def initialize(token, left, right) @token = token @left = left @right = right end attr_accessor :token, :left, :right end トークンと、 左右の Node を保持 6
  • 7. copyright© 2008 kuwata-lab.com all rights reserved サンプルコード: Variableクラス class Variable < Node def initialize(name) @name = name end attr_accessor :name end 変数名を保持 7
  • 8. copyright© 2008 kuwata-lab.com all rights reserved サンプルコード: 実行例 x = Variable.new('x') y = Variable.new('y') x + y * 2 #=> Expression.new(:'+', Variable.new('x'), Expression.new(:'*', Variable.new('y'), 1 ) ) + x y 2 * ...構文木をさらに変換 '+' より '*' の ほうが強い 8
  • 10. copyright© 2008 kuwata-lab.com all rights reserved 応用例:Ruby式をSQLへ # Ruby #=> SQL x == 10 #=> x = 10 x == nil #=> x is null x ** 3 #=> power(x, 3) Ruby式 構文木 SQL 参考: Operast (http://github.com/kwatch/operast/) 10
  • 11. copyright© 2008 kuwata-lab.com all rights reserved 応用例:Ruby式をSQLへ # Ruby #=> SQL x > Date.new #=> x > '2008-12-06' x =~ '%pattern%' #=> x like '%pattern%' x.in? [1,4,7] #=> x in (1,4,7) x.in? 10..20 #=> x between 10 and 20 参考: Operast (http://github.com/kwatch/operast/) 11
  • 12. copyright© 2008 kuwata-lab.com all rights reserved 応用例:O/R Mapper の Model class User set_table_name('users') @name = Variable.new('name') def self.name; return @name; end # or class <<self; attr_reader :name; end end User.name == nil #=> users.name is null 12
  • 14. copyright© 2008 kuwata-lab.com all rights reserved 言語の必要条件 ‣ 演算子がオーバーライドできること • Ruby • Python • C++ (演算子オーバーロード) ‣ 型がないこと or 型が変更できること • 「==」の戻り値の型が boolean に固定されている と、実現不可能 14
  • 15. copyright© 2008 kuwata-lab.com all rights reserved 問題点:オーバーライド不可 ‣ オーバーライドできない演算子がある • 例:Ruby1.8 では、「!=」は 「==の否定」に固定 ‣ 解決策: • 他の演算子で代用(「^」「<=>」など) • 「x.not」や「x.ne」(not equal) を提供 x.not == 1 #=> x != 1 15
  • 16. copyright© 2008 kuwata-lab.com all rights reserved 問題点:&& と || ‣ 「&&」と「||」はオーバーライドできない • 評価のショートカットがあるため ‣ 解決策: • メソッドで代用(「.and」「.or」) • bit 演算子で代用(ただし演算子の優先順位に注意) (x == 1) & (y == 2) #=> x = 1 and y = 2 16
  • 17. copyright© 2008 kuwata-lab.com all rights reserved 問題点:1 + x ‣ 「x + 1」は OK だが「1 + x」は NG ‣ 解決策:一時的に Integer#+ を override def sandbox begin Integer#+ に alias 名をつけて退避 Integer#+ をオーバーライド yield  ensure Integer#+ をもとに戻す end 17
  • 18. copyright© 2008 kuwata-lab.com all rights reserved 問題点:動作速度 ‣ 動作速度は、たぶん遅い • 自作 O/R Mapper で評価中 ‣ 解決策: • なさそう? • キャッシュもできない(or 逆に遅くなる) • 最高速である必要はない (気にならない程度の遅さならよしとする) 18
  • 20. copyright© 2008 kuwata-lab.com all rights reserved まとめ ‣ 演算子をオーバーライドして構文木を返す •「構文解析」ではなく「評価」 •Ruby の式をそのまま使う → DSLで使いやすい ‣ アイデア次第で面白い使い方ができるかも 20
  • 21. copyright© 2008 kuwata-lab.com all rights reserved 参考 ‣ SQLAlchemy (Python) • http://www.sqlalchemy.org/ ‣ Sequel (Ruby) • http://sequel.rubyforge.org/ ‣ RSpec (Ruby) • http://rspec.info/ ‣ Operast (Ruby) • http://github.com/kwatch/operast/ 21
  • 23. copyright© 2008 kuwata-lab.com all rights reserved こんな面倒なこと、本当に必要? ‣ Lispなら、同じことが「'」だけでできる ‣ 言語として必要な機能を Ruby が提供して いないだけでは? (+ x (* y 2) ) ;; 式が計算される '(+ x (* y 2) ) ;; 式の構文木が返される Lisp最強 23