成らぬは人の為さぬなりけり

エンジニアライフをエンジョイする為のブログ

PhantomJs+Vert.x(JRuby)でSockJsの疎通確認をしてみる

さて今回は、最近なにかとよく見るPhantomJsを使ってみようと思います。

背景

今、ちょっといろいろあって、
Vert.x+SockJsをやろうとしるんですが、以下のような問題が、、、

  • SockJsのクライアントがブラウザ用かnode.js用しかない
  • node.js用は、XHRStreamingにしか対応していない
  • Websocketで複数クライアントつなぐテストをしたい

そこで、PhantomJsを使ってブラウザからWebsocketでつなげてみよう、
と思って今回やってみました。

続きを読む

Scala2.10の新機能を勉強する その4 ValueClass(続編)

前回は、ValueClassの使い方を勉強しました。

  • メモリ割り当てが必要になる場合
  • 制約

を次回はやります。と宣言したんですが、
今回は「メモリ割り当てが必要になる場合」のみに絞りたいと思います。
※制約の話はその5とかで、、、

続きを読む

Scala2.10の新機能を勉強する その2 ImplicitClass

前回のつづきで、
今日はScala2.10のImplicitClassをやってみたいと思います。

環境

ImplicitClassって?

簡単に言うと、ImplicitConversionを楽に書ける機能、
と理解して良いんでしょうかね?
SIP-13 - Implicit classes - Scala Documentation

つまり

  • 変換する型の定義
  • 変換するメソッドの定義

が一発で書ける。

とりあえず、書いてみます。

ImplicitClassを書いてみる


こんな感じで書いてみました。
「HalfInt」はclassの定義とimplicit defの定義が必要ですが、
「DoubleInt」はimplicit classの定義だけで済んでいます。
これは確かに完結で良い。
ただ、これ、同じようにコンパイルされるんだろうか?
という事で、jadってみます。

package implicitclass;

import scala.Function0;
import scala.Predef$;
import scala.runtime.*;

// Referenced classes of package implicitclass:
//            ImplicitClass_01$

public final class ImplicitClass_01
{
    public static class HalfInt
    {

        public int half()
        {
            return i / 2;
        }

        private final int i;

        public HalfInt(int i)
        {
            this.i = i;
            super();
        }
    }

    public static class DoubleInt
    {

        public int _mthdouble()
        {
            return i * 2;
        }

        private final int i;

        public DoubleInt(int i)
        {
            this.i = i;
            super();
        }
    }

    public static class delayedInit.body extends AbstractFunction0
    {

        public final Object apply()
        {
            Predef$.MODULE$.println(BoxesRunTime.boxToInteger($outer.DoubleInt(1)._mthdouble()));
            Predef$.MODULE$.println(BoxesRunTime.boxToInteger($outer.toHalfInt(1).half()));
            return BoxedUnit.UNIT;
        }

        private final ImplicitClass_01$ $outer;

        public delayedInit.body(ImplicitClass_01$ $outer)
        {
            if($outer == null)
            {
                throw new NullPointerException();
            } else
            {
                this.$outer = $outer;
                super();
                return;
            }
        }
    }


    public static void main(String args1[])
    {
        ImplicitClass_01$.MODULE$.main(args1);
    }

    public static void delayedInit(Function0 function0)
    {
        ImplicitClass_01$.MODULE$.delayedInit(function0);
    }

    public static String[] args()
    {
        return ImplicitClass_01$.MODULE$.args();
    }

    public static void scala$App$_setter_$executionStart_$eq(long l)
    {
        ImplicitClass_01$.MODULE$.scala$App$_setter_$executionStart_$eq(l);
    }

    public static long executionStart()
    {
        return ImplicitClass_01$.MODULE$.executionStart();
    }

    public static HalfInt toHalfInt(int i)
    {
        return ImplicitClass_01$.MODULE$.toHalfInt(i);
    }

    public static DoubleInt DoubleInt(int i)
    {
        return ImplicitClass_01$.MODULE$.DoubleInt(i);
    }
}

ほぼ同じようにコンパイルされてるっぽい(?)

ImplicitClassを切り出してみる

次にImplicitClassを切り出してみます。

コメントにも書いてありますが、
implicit classをトップレベルで書けないようです。
以下のようなエラーになりました。

[error] /Users/xxxx/workspace/scala-samples/scala-2.10-sample/src/main/scala/implicitclass/ImplicitClass_02.scala:10: `implicit' modifier cannot be used for top-level objects
[error] implicit class TripleInt(i: Int) {
[error]                ^
[error] one error found
[error] (compile:compile) Compilation failed

importに関しては、implicit defで定義する時も同じような使いかたをするだろうし、
あまり変わらないかな??

今日は、ここまでにします。
次回はValueClassに挑戦。
(内容薄いですが、メモなので、、、、(逃

Scala2.10の新機能を勉強する その1 StringInterpolation

久々のブログですが、
今更ながらScala2.10の新機能をちゃんと勉強しておこうと思います。

※終わったらRuby2.0やろうと思ってますが、、、

今回のテーマ

StringInterpolation
です。

環境

StringInterpolationって?

Rubyの式展開のように、文字列リテラル内に、式を書く事ができる機能です。

Interpolationって、どういう意味だろうか、、、
初めて聞いたので、意味がわからず、、調べてみました。

alc

http://eow.alc.co.jp/search?q=interpolation&ref=sa
→〔他のものに〕挿入すること、差し挟むこと

なるほど、文字列になんか差し込むので、StringInterpolation、なんですね。
とりあえず言葉の意味は理解できました。

式を埋め込んでみる

まずは、単純に変数の値を埋め込んでみます。

これで、

Hello hoge!

となります。
Rubyの記法に比べると{}が無くて、#が$になった感じですね。

では、次に、計算式やらメソッド呼び出しやらを埋め込んでみます。

ここでは{}が必要な場面が登場しました。
変数もしくは引数なしのメソッド呼び出しは{}は不要ですが、
それ以外は必要になるようです。
※当然といえば当然ではある、、、。

フォーマットを指定して埋め込む

次はフォーマットを指定して値を埋め込んでみたいと思います。

ここで最後の行はエラーになりました。
コメントにも書きましたが、
piはDouble型になるので、Intを期待するフォーマット「%d」は使えません。
※コンパイル時にエラーになります

[error] /xxxx/workspace/scala-samples/scala-2.10-sample/src/main/scala/interpolation/StringInterpolation_03.scala:10: type mismatch;
[error]  found   : Double
[error]  required: Int
[error]   println(f"$hoge is $pi%2.4d") // これはpiがDoubleなので、エラーになる
[error]                       ^
[error] one error found
[error] (compile:compile) Compilation failed

仕組みを知る

このStringInterpolationの仕組みはStringContextのメソッド飛び出しで実現されているようです。
試してみます。

こんな感じ。

hoge"...."

これは

StringContext(....).hoge(....)

に展開されるようなので、
ImplicitConversionと組み合わせれば、他にも便利なリテラルが実現できそうです。

他の機能を勉強してからやってみたいと思います。

Scala勉強日誌 - Akka その1

Scala勉強日誌 - Actor - 成らぬは人の為さぬなりけり
大分前にActorの勉強して、続きでAkkaの勉強しようと思ってて、完全に忘れていたので、
再開したいと思います。
(仕事で必要になって、勉強したので、メモしているだけ、、、)

今日のテーマは、、、

  • SBTプロジェクトを作る
  • AkkaのActorを書いてみる
  • ActorからActorを呼び出して、結果を受け取ってみる
  • Routerを使ってみる。

yagince/akka_practice · GitHub

例によって、環境は、、、

  • OS:MacOSX10.8
  • Scala : 2.10.0
  • sbt :0.12.2
  • Akka : 2.1.0

SBTプロジェクトを作る

まずは、プロジェクトを作ります。
今回は、全部ビルド定義ファイルは全部Scalaで書きたかったので、
こんな感じで作成
project/Build.scala

import sbt._
import Keys._

object BuildSettings {
  val buildOrganization = "yagince"
  val buildVersion      = "0.0.1"
  val buildScalaVersion = "2.10.0"

  val buildSettings = Defaults.defaultSettings ++ Seq (
    organization := buildOrganization,
    version      := buildVersion,
    scalaVersion := buildScalaVersion
  )
}

object Resolvers {
  val typeSafe = "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
  val otherResolvers = Seq(typeSafe)
}

object Dependencies {
  val akkaCore = "com.typesafe.akka" %% "akka-actor" % "2.1.0"
}

object AkkaPracticeBuild extends Build {
  import Resolvers._
  import Dependencies._
  import BuildSettings._

  val dependencies = Seq (
    akkaCore
  )
  
  val project = Project (
    "akka-practice",
    file("."),
    settings =
      buildSettings ++ Seq (
        resolvers := otherResolvers,
        libraryDependencies ++= dependencies
      )
  )
}

project/build.properties

sbt.version=0.12.2

AkkaのActorを書いてみる

では、早速書いてみます。

src/main/scala/akka/sample/AkkaExample01.scala

package akka.sample

import actor.PrintActor
import akka.actor.{Props, ActorSystem}

object AkkaExample01 extends App {
  val system = ActorSystem("sample")
  val actor = system.actorOf(Props[PrintActor], "hoge")

  actor ! "HelloWorld!"

  system.shutdown
}
package akka.sample

import actor.PrintActor
import akka.actor.{Props, ActorSystem}

object AkkaExample01 extends App {
  val system = ActorSystem("sample")
  val actor = system.actorOf(Props[PrintActor], "hoge")

  actor ! "HelloWorld!"

  system.shutdown
}

src/main/scala/akka/sample/actor/PrintActor.scala

package akka.sample.actor

import akka.actor.Actor

class PrintActor extends Actor {
  def receive = {
    case x => println(x)
  }
}

実行結果

> run-main akka.sample.AkkaExample01
[info] Running akka.sample.AkkaExample01 
HelloWorld!
[success] Total time: 0 s, completed 2013/02/13 22:16:22

単純に渡したオブジェクトを出力するだけのアクターです。
これだけ見ても、scala標準Actorより記述量が少ないですね。
そして、シンプル!
素晴らしい。

ActorからActorを呼んで結果を受け取ってみる

Scala標準Actorの同期メソッドみたいのあるのかな??
無さそう???と思っていたら、
こんな風にするのが普通なのかな???
というわけで書いてみます。

package akka.sample

import akka.actor.{ActorSystem, Actor, Props}
import akka.routing.RoundRobinRouter

object AkkaExample02 extends App {
  val system = ActorSystem("sample")
  val actor = system.actorOf(Props[Master])

  actor ! 100

  Thread.sleep(500)
  system.shutdown
}

class Master extends Actor {
  val actor = context.actorOf(Props[DoubleActor])

  def receive = {
    case i:Int => actor ! i
    case Doubled(x) => println("received : %d".format(x))
  }
}

class DoubleActor extends Actor {
  def receive = {
    case i:Int => sender ! Doubled(i*2)
  }
}

case class Doubled(i:Int)

senderへ結果を返して、呼び出し側のreceiveへメッセージパッシングする感じですかね?
確かに、これはシンプルで綺麗だ。
よくよく考えると、同期メソッドって必要ないんじゃなかろうか、、、

Routerを使ってみる

AkkaにはRouterという機能があるようです。
Actorのインスタンスを管理して、
Routerにメッセージ送信すると、
Actorへよしなにバランシングしながらメッセージを横流ししてくれるような感じでしょうか?
書いてみます。

package akka.sample

import actor.{Doubled, DoubleActor}
import akka.actor.{ActorSystem, Actor, Props}
import akka.routing.RoundRobinRouter

object AkkaExample02 extends App {
  val system = ActorSystem("sample")
  val actor = system.actorOf(Props[Master])

  (0 to 10).foreach(actor ! _)

  Thread.sleep(100)
  system.shutdown
}

class Master extends Actor {
  val router = context.actorOf(Props[DoubleActor].withRouter(RoundRobinRouter(2)))

  def receive = {
    case i:Int => router ! i
    case Doubled(x) => println("received : %d".format(x))
  }
}
> run-main akka.sample.AkkaExample02
[info] Running akka.sample.AkkaExample02 
received : 0
received : 2
received : 6
received : 10
received : 4
received : 14
received : 8
received : 18
received : 12
received : 16
received : 20
[success] Total time: 0 s, completed 2013/02/13 22:27:41

一個前の例のMasterクラスを書き換えて、
DoubleActorをRouterで管理するようにしてみました。
Routerの種類は

  • akka.routing.RoundRobinRouter
  • akka.routing.RandomRouter
  • akka.routing.SmallestMailboxRouter
  • akka.routing.BroadcastRouter
  • akka.routing.ScatterGatherFirstCompletedRouter
  • akka.routing.ConsistentHashingRouter

Routing (Scala) — Akka Documentation
これだけあるようです。
それぞれの違いは、また次回ということで、、、

さて、今日はここまでにします。

CoffeeScriptを書いてみる その2

前回は、
関数定義、文字列内変数展開をやってみました。
さて、今回のテーマは、、、

  • 可変長引数
  • レンジ
  • 比較演算子
  • 条件付き代入
  • 無名関数

をやってみたいと思います。

可変長引数

関数の引数に「...」をつけると可変長引数になります。

hoge = (ary...) ->
  console.log ary

hoge 1,2,3,4,5  

実行結果

[ 1, 2, 3, 4, 5 ]

ちゃんと配列で取得できているようですね。

レンジ

配列をレンジ(範囲)で作成することができます。
書き方はRubyとほぼ同じでした。

range = [1..10]
console.log range

実行結果

[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

逆順にすることもできます。

reverse_range = [10..0]
console.log reverse_range

実行結果

[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ]

「..」を「...」にすると、右端を含めないレンジになります。
※昇順でも降順でも同じ

reverse_range_2 = [10...0]
console.log reverse_range_2

実行結果

[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]

比較演算子

等価比較

CoffeeSriptでは「==」を使うと「===」にコンパイルされます。
なので、==で型も含めた比較になります。
※CoffeeScriptにはJavaScriptでいう==に相当する比較演算子は無いそうです。

console.log 1 == "1"

実行結果

false

では、同じ事をJavaScriptでやってみます。
今回はNode.jsを使ってやってみます。

$ node
> 1 == "1"
true
> 1 === "1"
false

「1=="1"」はJavaScriptではtureになりますね。

「==」以外にも「is」という演算子が用意されています。

coffee> 1 is "1"
false

※ファイルに書くのがめんどくさくなってきたので、辞めました。。。
「is」は「===」にコンパイルされるようです。
他にも自然言語でかける演算子がいくつか用意されています。

coffee> 1 is "1"
false
coffee> 1 isnt "1"
true
coffee> not true
false
coffee> not 1
false
coffee> not undefined
true
coffee> not null
true
coffee> true and false
false
coffee> yes
true
coffee> no
false
coffee> false or true
true

こういうのはコードが非常にリーダブルになるので好き。

存在確認をする演算子もあります。

coffee> hoge?
false

RubyActiveSupportのObject#tryのような使い方もできます。

coffee> hoge?.foo
undefined
coffee> hoge = {foo: "foo"}
{ foo: 'foo' }
coffee> hoge?.foo
'foo'

条件付き代入

nullもしくは、undefinedの場合のみ代入する。
foo = null
foo ?= "foo"
console.log foo

実行結果

foo

※これはREPLからやると、エラーになる、、、

ちなみに、「?=」で代入する場合、変数「foo」は定義されている必要があります。
fooが未定義の場合


Error: In foo.coffee, the variable "foo" can't be assigned with ?= because it has not been defined.

と怒られました。

falseの時のみ代入する
bar = false
bar ||= "bar"
console.log bar

実行結果

bar

ちなみに、これもbarが定義されていないと怒られます。
これは、Rubyと同じで、条件的にfalseと判定できればなんでもいけるのか??
というわけで試してみます。

a = false
a ||= "Yes"
console.log a

b = 0
b ||= "Yes"
console.log b

c = null
c ||= "Yes"
console.log c

d = undefined
d ||= "Yes"
console.log d

e = ""
e ||= "Yes"
console.log e

実行結果

Yes
Yes
Yes
Yes
Yes

なるほど。
変数が定義されてさえいれば、あとはRubyと同じようなノリなのかな。

変数が定義されていない場合に代入する、というのは、こんな感じで書くんでしょうか?

coffee> hoge = hoge ? "hoge"
'hoge'

無名関数

最後に、無名関数を関数の引数に渡す場合の書き方です。
基本的には、関数定義時となんらかわりありません。

setTimeout ->
  console.log "Hoge"
, 1000

実行結果

$ coffee nameless.coffee                                                                                                    
Hoge

一秒待って、Hogeと表示されます。
ちなみに、当たり前な事ではありますが、こう書くと、意図しない動きになります。。。

setTimeout ->
  console.log "Hoge"
  , 1000

実行結果

$ coffee nameless.coffee                                                                                                    
Hoge 1000

setTImeoutに対して、

console.log("hoge",1000)

を呼び出す関数を渡した事になるので、当たり前ではありますが、
最初ちょっと???になりました。
(インデントに慣れていないので、、、)

今日はここまで。
次は配列の操作とかクラス定義とかやろうと思ってます。