Furyu
[フリュー公式]

Tech Blog

フリュー株式会社の技術ブログです

2014年01月17日

kunihira

Scala-return文を色々に呼び出してみた

あけましておめでとうございます。

フリュー ソフトウェア開発部 国平です。

今年もよろしくお願いいたします。


前回の記事で、自身のプリクラと逆変換した画像を載せたところ、

「キレイなジャイアンみたい」とか、

「逆変換してもまだ本物よりイケメン」とか散々言われまくってます。

なので、今日は画像なしで、Scalaのreturn文の挙動について文章だけで勝負します。

発端

皆様、リーダブルコードという本はご存知でしょうか。

タイトルそのまま、読みやすいソースコードを書くためのテクニックが書かれた本です。 非常に読みやすく、しかもエッセンスを抽出してコンパクトにまとめられた良書です。

この本の中で、return文に関するTipsとして「関数からはやく返す」という項目があります。 これは「早い段階で、結果を返せるのであれば、さっさとreturnしましょう」ということで、 私はそれに従ってコードを書いていたのですが、隣の席の人にコードを見せると、

「Scalaっぽくない」という話になって、確かにその通りなのでコード自体はreturn文を使わないように変更しました。

その時に書いたreturn文ありのコードはこんなイメージです↓

この時ふと、「Scalaって引数に関数を渡せるけど、じゃあreturn文を書いた時に、どの関数の結果になるんだ」という話になっていろいろ試すことになりました。

というわけで、ScalaのREPLで色々なreturn文を試してみました。

ケース1

とりあえず、裸のreturnを書いてみました。

return文をメソッド定義の外に書くなって怒られました(´Д⊂グスン

こういうの↓も同様です

これならどうだ

戻り値型を定義しろって、また怒られる(´・ω・`)

というわけで、これだっ

はい、当然のように3を返す関数が出来ました。

ここまでのまとめ

  • 関数定義の中からしか呼び出せない
  • 関数の戻り値型の定義が必要

ケース2 高階関数で利用

さて、ここからが本題

関数型言語らしく高階関数の中でreturn文を呼び出してみたらどうなるか実験します。

まずは、Int型を返す関数を引数にとる関数barを定義します。 関数barは、第1引数boolがtrueであれば、第2引数のblock関数を実行した結果に+1して返します。

試しに呼び出すと、引数を1を返す関数として認識して、+1して処理してくれてます。 なので、結果は2になりますね。

この関数引数にreturn文を書いてみます。

あれ?また関数定義の外でreturnしちゃだめって怒られました。 ぬぬぬ、barは関数を引数に取ることを明記してるけど、どうやらダメらしい。

というわけで、これでどうよ?

関数bazzの定義の中で、関数barを呼び出して引数にreturn 1を渡しました。 さて、どうなるのか…

関数bazzの戻り値が1になっとるッッ

結局、高階関数の引数にreturnを書いても、そのreturn文がどのメソッド定義の中に書かれているかが重要なようです。 まぁ、エラーメッセージ通りってことですね。

では関数bazzの引数をfalseにしたらどうなるのか?

お!4が帰ってきた!

ここまでのまとめ

  • 高階関数でもベタにreturn文を書くことはできない→明示的な関数定義が必要
  • return文が扱う制御は、return文が書かれた箇所で明示的に定義されている関数
  • ただし、return文の処理タイミングは高階関数で制御できる

総括

というわけで、Scalaのreturnは明示的に宣言された関数の制御文として動作することがわかりました。 しかし、高階関数と組み合わせて使いはじめると、一体どのタイミングでreturn文が実行されるのか、ワケガワカラナイヨなので、わざわざ使わないほうが良さそうです。

実際にreturn禁止のスタイルガイドもあるみたいです。というか、Scalaの作者がそう言ってるみたいです。 stackove – Scala coding styles and conventions?

関数内の見通しが悪くなるからreturnで処理を中断したいと思うような場合は、メソッド分割などを駆使して、そもそも関数が長くなりすぎたり、インデントが深くなり過ぎないようにしましょう。


2013年11月15日

kasuya

CentOSでScalaからSoXを使って音声ファイルを操作する手順

ソフトウェア開発部、粕谷(@daiksy)です。

今回は音声ファイルの操作についてのお話です。

我々のチームでは、ソーシャルゲームのサーバサイドの開発・運用を行っています。
昨今のソーシャルゲームは、アニメーションや音声の再生など、一昔前に比べて表現がずいぶんリッチになっています。

そのような流れの中で、我々のチームでも音声ファイルの操作について検証をはじめました。

別にどのような技術を用いても良かったのですが、我々のチームでは、ゲームのサーバサイドのシステムをPlay + Scalaで構築しており、どうせならScalaから音声ファイルを操作しようと思いました。

やりたいことは、

  • wav -> mp3 などの形式変換
  • 音声ファイルのサイズ(再生秒数)の取得
  • 複数の音声ファイルの結合

の3要件です。

我々が扱っているScalaは、JVMで動作する言語であり、Javaの豊富なライブラリを使用することができます。
そういったライブラリ群を用いれば、音声ファイルの操作は行えるでしょうが、今回はそれらを使わずにSoXというツールをScalaから呼び出すことで要件を実現することにしました。
理由は、SoXは基本的にコマンドラインで音声ファイルを操作するツールなので、Scalaからこれらのコマンドを呼び出せば、Javaのライブラリを使うよりも楽に要件が実現できそうだったからです。

まとめると、システム構成は以下のようになります。

  • OS: CentOS 5.5
  • 使用言語: Scala
  • 音声ファイル操作: SoX

まず、最初の手順としては、SoXをCentOSにインストールする必要があります。
インストールは実に簡単で、wgetで最新版をとってきて解凍し、makeするだけです。  

 
これだけで、SoXは使えるようになるはずです。しかし、CentOSを扱っている場合は注意が必要です。  

 
を実行すると、SoXの設定状態が一覧表示されます。この時点での設定状態を見てみましょう。
注目すべきはこの部分です。  

 
ご覧のように、mp3がサポートされていません。
今回、我々はmp3のファイルを扱う必要があるのですが、CentOSはデフォルトではmp3を扱えないのです。 そこで、mp3を扱うために必要なライブラリを入れましょう。  
こちらのサイトを参考にしました。  

 
再度、SoXをmakeします。  
 

 
これで、SoXの状態が下記になっていれば準備完了です。    

 
サーバでSoXさえ動くようになれば、Scalaからこれを呼び出すのは容易です。  
ScalaからOSのコマンドを叩くには scala.sys.process を使います。
これは非常に強力で、import scala.sys.process._とimportすると、Scalaの暗黙の型変換(implicit conversion)によってStringにプロセスを実行するメソッドが拡張されます。  
例えば、  

 
を実行してやると、変数retls -lコマンドの実行結果が格納されます。
詳しくは、こちらをご参照ください。  
この scala.sys.process と、Scala2.10のString Interpolationを組み合わせることで、可読性も非常に高くSoXコマンドを扱うことができます。
それぞれのコード例を見てみましょう。  
 
例1) wav -> mp3 の形式変換

 
例2) 音声ファイルのサイズ取得

 
例3) 複数の音声ファイルの結合

 
非常に簡単ですね!!


2012年10月9日

kunihira

play-velocity-plugin公開!

皆様、お久しぶりです。

国平です。

さてこの度、弊社で開発し実際のプロダクト上で利用されているplay-velocity-pluginをオープンソース化することができました。

play-velocity-plugin

弊社では初のOSSプロジェクトとなります。

play-velocity-pluginはその名の通り、Play!Framework2 上で動作するVelocityTemplateプラグインです。

今日は、このプロジェクトのメイン開発者直々の押し付…ぢゃない、指名を受けてプラグインの紹介をさせて頂きます。

前回の記事にあります通り、弊社では現在ソーシャルゲーム開発において、Play!Framework2とScalaを用いた開発を行なっています。

そのことについては、粕谷がPlay!Framework勉強会第3回で導入事例を発表させていただきました。

Play勉強会 第3回 from Daisuke Kasuya

この資料でも、play-velocity-pluginの公開については言及されていますが、ついに実現しました。

今回は、このプラグインを導入によるメリットについて宣伝させていただこうと思います。

なぜScalaTemplateをやめたのか

Play!Frameworkは基本的にはフルスタックのWebフレームワークです。

そのため、テンプレートエンジンについてもデフォルトでScalaTemplateを利用することができます。

Play! The template engine

このScalaTemplateの特長として、

  • Scalaの強力な構文が利用できる
  • コンパイルされることによりバグが回避される

といったメリットがあります。

特に、コンパイル時にきっちりと変数がセットされることや、変数の型、メソッドやフィールド呼び出しの記述ミスがチェックされるので、バグの入り込むスキを少なくしてくれます。

しかし、粕谷の資料でも言及されているとおりトレードオフとして、

  • Scala構文がデザイナによる変更の容易性を下げている 
  • HTMLのちょっとした変更でもコンパイルが要求される

という問題が発生してしまいます。

その他にも、ScalaTemplate採用プロジェクトがある程度進行した時点で起こった問題として、テンプレートファイルがすべてコンパイル対象となってしまうので、コンパイルの際に非常に多くのマシンリソースが要求されてしまいました。

3年前のPCのマシンスペックではコンパイルに10~15分かかることもあったようです。

更には、デフォルトのJVMへのメモリ割り当てでは容量が足りずコンパイルが失敗するため、ビルドスクリプトを直接編集して利用メモリを増やすという対応も必要となりました。

このような問題があり弊社で以前から利用実績のあるVelocityをテンプレートエンジンとして採用することとなりました。

Velocityの特長

VelocityはApacheFoundationで公開されているJavaベースのテンプレートエンジンです。

Apache Velocity

もともと、弊社ではPlay!Frameworkの採用以前からS2ファミリーを利用しており、テンプレートエンジンとしてS2Velocityを利用していました。

このVelocityなのですが、特長として

  • スクリプト言語ライクに動作する(コンパイル不要) 
  • Webデザイナにも変更がしやすい(構文がわかりやすい)

という特長があります。

もちろん、トレードオフとして、

  • バグチェックが難しい
  • 記述が冗長になる

という問題点もあります。

また、Velocityはレンダリング速度が遅いのではないのかという懸念もありましたが、Velocityを採用する際のベンチマークからも十分な速度でレスポンスを返せることが証明されていますし、サービスを運営している中でレンダリング速度が問題になったことはありません。

VelocityとScalaTemplateの比較

今回は、ソーシャルゲームというサービスの特性上、リリースサイクルの短縮が大きな課題となります。

そのため、変更からリリースまでの時間と、デザイナーの作業の行いやすさという点から比較します。

デザインの変更から反映までのステップを下の図に示しますが、これだけでリリースサイクルという観点からはVelocityのメリットが充分に感じられると思います。

まとめ

このように、play-velocity-pluginはデザイナとの協業、リリースサイクルの短縮という点において利点があります。

既にOSSとしてGitHubおよびMavenリポジトリに公開してありますので、Play!Framework2をご利用の方は、ぜひ試してみていただきフィードバックをいただければと思います。

社内だけでなく、皆様のご意見も頂いた上で、今後このplay-velocity-pluginを育てていきたいと思っています。

また、近いうちにplay-velocity-pluginを実際に利用するノウハウなどもこのブログで紹介していきたいと思います。


2012年10月2日

kasuya

DevLOVE関西 2012 Drive にて、乙女ゲームの開発事例をお話させていただきます

ソフトウェア開発部の粕谷(@daiksy)です。

11月10日(土)に、大阪で「DevLOVE関西2012Drive」というイベントが開催されます。

そこで、スピーカーとして「乙女ゲーを支える技術」というセッションを担当させていただくことになりました。

■DevLOVE関西2012Driveとは?

このイベントは、DevLOVEという開発者コミュニティが主催する勉強会です。今年のテーマは”Drive”。

技術とファシリテーションが前輪と後輪となって、開発を駆動していく、というマルチセッション方式の勉強会となっています。

■発表内容

弊社では今年、play2.0 + Scalaという技術を使って数本のソーシャルゲームを開発しました。

わたしも、乙女ゲーの開発に携わり、これらの技術を用いた開発を経験しました。

開発言語として関数型言語が注目される昨今において、この開発事例は多くの方に興味を持って頂き、いくつかの勉強会でお話する機会をいただいています。

play2.0 + Scalaでの開発において、現場でどのようなことがあったのか。

弊社のエンジニアは、それらの技術をどのように身につけ、リリースを迎えたのか。

そういった開発事例をいくつかのエピソードとともにお話しようと思っています。

他にも、大変魅力的なセッションが目白押しなので、是非お越しください。

みなさんとお会いできるのを楽しみにしています。