Blog

RubyistがScalaを勉強してみた


DSC03362

 

初めまして!新卒のフィです。

RightSegmentという子会社でエンジニアをやっています。

大学時代からずっとRubyやPython, JavascriptなどのLL系の言語を使用しており、たまにJavaでAndroidアプリを書くぐらいなので、型言語を触るのは久しぶりです。アドテクスタジオでは多くのプロダクトでScalaが利用されており、今回はじめてScalaについて調査しました。

Scala言語は調べれば調べるほど楽しそうですが僕はプログラミング言語の中ではRubyが一番好きなので、Ruby言語の特徴をScalaで再現してみました。

  •  method_missingを使ったActiveRecordのパターン
  • 既存の演算子をオーバーライドできる
  • Duck Typingができる

この三つのパターンをScalaで実現するか、また実現できたらどうなるかをやってみました。

今回の記事では、ActiveRecordパターンをScalaで実現することを試しました。

 

ダイナミックにActive Recordのパターンを実現

 

1. ActiveRecordパターンとは

Wikipediaの定義により

Active Recordはデータベースからデータを読み出すためのアプローチである。データベーステーブルあるいはビューの1行が1つのクラスにラップされ、オブジェクトのインスタンスがそのデータベースの1つの行に結合される

Ruby On Railsには、例えば、People というデータベーステーブルがあります。そのテーブルの中に、name, ageというフィルドがあります。そのテーブルに紐づくモデルが Person とすると(注:Railsではテーブル名が複数形、コード上のモデル名は単数系ではないといけない)

の二つのメソッドが自動的に作成されます。(不思議ですよね。)

Rubyでは、もしメソッドが見つからない場合は、ExceptionをRaiseする前に、method_missingというプロキシメソッドを通って、見つからない関数名+パラメータをmethod_missingに渡す挙動を取ります。

そのため、Personのmethod_missingメソッドをオーバーライドすることにより、ある名前に該当するメソッドをランタイムに作れます。

みたいな感じで、メソッドがランタイムに作れます。

ではScalaではどのようにmethod_missingを実現するか見ていきましょう。

 

2. ScalaでDynamicにActiveRecordパターンを実現する

2.1 自由のメソッドを作れるようにDynamic traitを活用

Scalaでは、メソッドが見つからない場合はどうなるかを実装してみると

コンパイルしてみると

コンパイルするときに怒られました。

ウェブで探してみると、DynamicというタイプがScala 2.10から追加され, Dynamicは Scala で”動的にメソッドやフィールドを定義するため”のものです!

実現したイメージがDynamicで実現できそうなので、早速試してみます。

でコンパイルしてみたら、

また、コンパイルするときに怒られました。

Scala-lang.orgの資料を読んでみると、以下の例があります:

なるほど、つまり存在していないメソッドは自動的にapplyDynamicというメソッドにディスパッチするみたいですね。そのまめ、Personクラスの中にapplyDynamicを定義しないといけない。資料をみたら、applyDynamicは二つのパラメータを受け取って、一つ目はメソッド名、二つ目はパラメータの配列です。

コードを書き直してみますと:

と出力されました!

やった!Rubyライクにメソッド見つからないときにプロキシメソッドを通して、自由な処理ができるようになりました。

 2.2 RubyのActiveRecordのようにDB接続まで書いてみよう

JDBCを利用してデータベースに接続してみます 。例なのでデータベースconnection管理の部分は省略します

Let’s connect!


やった!ちゃんと動きました!!!!!

 3.説明

上記ではScalaのDynamic traitを利用し、Active Recordを実装してみました。

これにより

  1. テーブル名をクラス名で自動的にマッピングされ、一つのテーブルイコール一つのクラスを簡潔に表せる。
  2. フィールド名を関数名から推測され、呼び出す側が楽になる

という二つのメリットが得られます。

もちろんDynamicのやり方をやり過ぎには注意です。

  1. 一番大きいデメリットはコードをgrepできない、または参照場所がわかない。。
  2. デバッグしづらい
  3. ちゃんと設計しないとコードが一つのところ(applyDynamic)に集まり過ぎて、雑なコードになりやすいです

うまくDynamicを利用していきたいですね

次回には演算子オーバーライドとDuck Typingについて話をしたいですので、是非を楽しみにしてください!

 

 

Copyright about logo
Copyright (C) 2008 合同会社Rubyアソシエーション
Copyright (c) 2002-2015 EPFL

Author

アバター
admin