2013年7月22日月曜日

Kotlin勉強会に行くのでちょっとだけ予習した

多分日本初という触れ込みの勉強会に行くので予習したメモ

ただし、主催者は現状こんな感じらしい





kotlinの未来が不安ですね…



というわけで超適当に以下のkotlinの基本文法を眺めてみた

https://sites.google.com/site/tarokotlin/3-kotlinno-biao-zhunapi



そうそう、 Comparision to Scala ってページがあるので開くと…

If you are happy with Scala, you probably don't need Kotlin.

らしいです

あれ、じゃあ終わり?



スマートキャスト


is演算子で型チェックしてたら、それはもうその型とみなして動かしてええで!
みたいな感じらしいです

fun sayHello(target : String) {
println("Hello, $target!")
}
val target : Any = "world"
if(target is String) {
sayHello(target) // Hello, world!
}
view raw 1.kt hosted with ❤ by GitHub


ちなみにScalaにはねーよってDocumentに書いてます

同じようなことしようとするとこんな感じ?

def sayHello(target : String) = println(s"Hello, $target!")
val target : Any = "world"
target match {
case x:String => sayHello(x)
case _ =>
}
view raw 1.scala hosted with ❤ by GitHub


うん、パッとは思いつかんけど同じような挙動だよね

関数


defかfunかの違いくらい?
ローカル関数もあるし〜

と思ったらローカル関数でなかなか面白いことが

fun isUpperCase(str : String) : Boolean {
fun String.all(f : (Char) -> Boolean) : Boolean {
for(val c in this) {
if(!f(c)) {
return false
}
}
return true
}
return str.all {
Character.isUpperCase(it)
}
}
view raw 2.kt hosted with ❤ by GitHub


拡張関数というものが混じっている

Scalaだったら暗黙の型変換とかで同様のことを頑張る感じ?

def isUpperCase(str : String) : Boolean = {
implicit class MyRichString(val self : String) {
def all(f : Char => Boolean) : Boolean = self.forall(f)
}
str.all(Character.isUpperCase)
}
view raw 2.scala hosted with ❤ by GitHub


まあサンプルと同じ内容なら

str.forall(_.isUpper)

でいいじゃん?とは突っ込まない

関数リテラル


kotlinだと関数は引数として渡せないよと。
渡すなら関数リテラルでと。

fun run(f : () -> Unit) = f()
// リテラルじゃないから引数として渡せないらしい
//fun sayHello() {
// println("Hello")
//}
val sayHello = {
println("Hello")
}
run(sayHello)
view raw 3.kt hosted with ❤ by GitHub


def run(f: () => Unit ) = f()
val runLiteral = (f:() => Unit) => f()
def sayHelloFunc() = println("Func!!")
val sayHelloLiteral = () => println("Literal!!")
run( sayHelloFunc )
run( sayHelloLiteral )
runLiteral( sayHelloFunc )
runLiteral( sayHelloLiteral )
view raw 3.scala hosted with ❤ by GitHub


scalaの場合、関数から関数リテラルに変換できるからだろうかどっちでもOK
そういや深く考えたことねーわ…

// aliasと言って良いのか…?
val alias = sayHelloFunc _

kotlinにも関数から関数リテラルに変換するやつがあれば結局一緒な気がする

when式


matchとどう違うのか… と思ったけど、割りとswitch文よりな感じ?
(ただしcontinue書いたらコンパイル通らなかったし、まだ未実装?)

なので5.2のパターンマッチングを見てみた

when(pair) {
is #(0, 0) -> "(0, 0)"
is #(0, Int) -> "(0, Int)"
is #(Int, 0) -> "(Int, 0)"
is #(Int, Int) -> "(Int, Int)"
is #(String, String) -> "(String, String)"
else -> "unknown"
}
view raw 4.kt hosted with ❤ by GitHub


val pair:(Any, Any) = ...
pair match {
case (0, 0) => "(0, 0)"
case (0, _:Int) => "(0, Int)"
case (_:Int, 0) => "(Int, 0)"
case (_:Int, _:Int) => "(Int, Int)"
case (_:String, _:String) => "(String, String)"
case _ => "unknown"
}
view raw 4.scala hosted with ❤ by GitHub


同じように書いたらこんな感じ?


ちなみにweb demoだと Tuples are not supported. Use data classes instead. って怒られる…
→ 後のデータクラスの章で悲しみの答えが!

流れでバインディングパターンも

val pair : #(String, Int) = #("taro", 23) // ← 先日25歳になっていたような…w
if(pair is #(val a, val b)) {
println("$a ($b)") // taro (23)
}
view raw 5.kt hosted with ❤ by GitHub


val pair = ("taro", 23)
// スマートキャストとおんなじような事やるならパターンマッチも使えばいいかな
val (a, b) = pair
view raw 5.scala hosted with ❤ by GitHub



分解者パターン:// あとで書く!


とあるけど、きっとExtractorとおんなじような感じなのかな…?と脳内で勝手に完結

for とか while とか ジャンプとリターン とか


ラベル付きのbreakができるよ!らしい
この辺とかはjavaよりも強力ですよ〜な売りになるんだろうか

その他


四章チラ見して記憶したこと

out/inで共変/反変

staticなメソッド持てないよ 代わりにobjectってあるよ

5章ちら(ry

https://sites.google.com/site/tarokotlin/chap5/sec54
null安全かOptionかは使う人によって良し悪し変わるんだろうなぁ…

https://sites.google.com/site/tarokotlin/chap5/sec55
データクラスってケースクラスみたいなもんかな?
そしてさり気に一番下に「マイルストーン3以降では、タプル機能は廃止されています。」
の文言が…/(^o^)\



各所チラ見した感想としては、確かにScalaで満足してたらKotlinは要らんよ?

って感じなんだろうなぁ…と

まあそんなこと言い出したら、別にどの言語でもそれでいいじゃんになりそうな気はする。

ScalaとKotlinって、それ(Scala | Kotlin)で見たよ!
みたいな感じにお互いがなるんですかね。

ってことでざっくりテキトー予習終わり

おまけ


sbt → simple build tool
kbt → kantan build tool

だったら面白かったのに…(これが書きたかっただけだったりw)

2013年5月4日土曜日

yeoman + angularjs + coffee をちょっと触ってみた

具体的な内容はQiitaに投稿してみた

http://qiita.com/items/454755dcd0a28eab15ee

割と最近Qiitaをのぞくことも多くなったので自分も投稿してみた的な

でQiitaからGistへの投稿も出来るっぽく試したところかなり残念だった…

どう残念かはこっち

Markdownそのままコピーかとおもいきや、そうなるのかよwww みたいな。

とりあえずこれでGWにやるべきことが半分片付いた(白目

2013年3月19日火曜日

#TDDBC Tokyo 2013-03 に参加してきました

いつかは行ってみよう〜っと思っていたTDDBCに参加して来ました。

TDDはもちろんペアプロがすごくよい経験になった、というのが最大の感想です

ドライバーとナビゲーターの入れ替えをあんなに頻繁にやるものなんだ…ということだけでも個人的にはすごくプラスになりました。

主催者やTAの方々、そして当日自分の環境に合わせてペアを組んでくれた @akuraru さん ありがとうございました。

そしてVOYAGE GROUPさん、タダ酒ありがとうございました素敵な会場ありがとうございました。

お題とか詳細は皆さんが各所でまとめてますし、togetterにもまとまってますのでそちらで。





と言ってしまったので書きます。

まず、こんな環境でした。

  • scala2.10 + specs2 + sbtでtestぶん回し

多分気になっている人もいると思いますし、一応こうやりました的なことを書いていきます



TODOもコード?



えーっと、半分本当で半分ウソです。

specs2ではこのような書き方が可能になります。

import org.specs2._
class LtsvSpec extends Specification {
def is =
"TDDBC 2013-03-16 Tokyo".title ^
"""
LTSVを読み込むクラスを作る
今回 @akuraru さんとペアになって短時間で考えた結果
基本的にMapでKey/Valueを保持し
Keyの順番に関してはListで管理することにした
"""^ p^
"LTSV一行を管理するクラス" ^
p^
"key value をsetする場合" ^ set^
"keyを指定して値を取得する場合" ^ get^
"dumpメソッドで出力する場合" ^ dump^
end
def set =
"key/valueを与えるとMapとListが更新される" ! pending ^
"既に保有するキーの場合は、Mapのvalueが更新され、" +
"Listで管理するkeyの順序は更新するキーが最後尾に来る" ! pending ^
"正常系ならEither::Right(None)が返る" ! pending ^
"正常系且つ更新ならEither::Right(Some(古いvalue))が返る" ! pending ^
"keyがnullの場合はLeft" ! pending ^
"keyが空文字はLeft" ! pending ^
"valueがnullはLeft" ! pending ^
"valueは空文字はOK(Right)" ! pending ^
endp
def get =
"keyが存在すればSome(value)が返る" ! pending ^
"keyが存在しなければNoneが返る" ! pending ^
endp
def dump =
"dumpは tab区切り末尾改行のLTSVで出力する" ! pending ^
endp
}


pendingを空のチェックボックス代わりに使っているだけです。
pendingを実際にテストを行うメソッドに書き換えればチェックした!みたいな。
詐欺ですねw

この書き方(specs2のサイトではacceptance specifications とあるので、受け入れテストを前提としている書き方?)だと(甘めに言えば)そのままTODOリスト書いているのと変わらない形で書けますので、
TODOリストもScalaで書いた( ー`дー´)キリッ
と言っても許され…ますよね?

というのを誇張しました、スミマセンでした。

他にもgradle同様HTML出力とかもしてくれますし、spock同様DataTablesもありますし、specs便利です。

ちなみにhtml出力画面はこんな感じ。



話それますが機会があればgradle+spockはとても触りたいですね。
あとScalaTestで同じようなことが出来るかどうかは、使ったこと無いので知りません、ごめんなさい。





なるほど…(ぉぃ
まあnullとか例外とか嫌ですよね。

で、先ほど当日未実装だった部分をテキトーにやったところ、ソースの行数が30行ぐらいになっちゃった。

改行だけの部分のカウントを除いて、dumpメソッドを再度ワンライナーに戻して、あと何かすれば10行程度になるかも?

何れにしても自分のScala力と今回のお題(Exception返せ!とか)だと10行は難しいかも…

ましてやvar使っちゃったし、もう負けてる感満載w



sbtでぶん回す



最近sbtは酢豚と読むらしいです(scala conference jpでそう聞いたw)

sbtではtestと叩くとtestが全実行されますが、「~test」で実行するとファイルが変更される度にtestを回してくれるので大変便利です。
コード書いてセーブすれば勝手に実行される素敵環境がすぐ出来ます。
PCのパワーと電源がある限りひたすらぶん回しておけばいいのです(ぇ

ただ正直なところ…テストケース一つを実行するならJava+JUnit+QuickJUnitのほうが体感速度は速くて気持ちいいと思いますw
Scalaもテストの実行そのものは早いんですけど、コンパイル待ちが…うーん…

結論:もっとマシンパワーがあればなんとかなる



あんまりここで書いちゃうと水曜日の「Scalaを勉強する会」でしゃべることがネタOnlyになっちゃうのでこのへんで許してください。

一応githubにソース置いてますので、興味がありましたら御覧ください。
あ、もちろん「フツーこう書くだろJK」的なご指導ご鞭撻もよろしくお願いします。

https://github.com/daneko/tddbc




そうそう、ペアプロにおいて環境の違いはどうやって埋めるべきなんでしょうね?
自分の環境(Intellijにvimプラグイン)とかだと、相手がemacs派だったりした場合とか…







あー、仕事でScala書きてー…

2013年3月10日日曜日

Intellij IDEA で少しだけPHPを書くのが楽になるかもしれない方法

去年末の75%offの際に Intellij IDEA 買いました。

いやもう凄い便利です、PHP書くときに… (´;ω;`)

ってことで本当は年初にでも書けばよかったんですけど…
かなり今更感ありますが取り敢えず書いとこ〜ってことで書きました。

あと今月から個人的にはもうPHPほとんど書く予定はない! はず…

Intellij IDEA で少しだけPHPを書くのが楽になる方法

IDE使うならやっぱりバリバリに補完が効くほうが良いですよね?

ということでPHPをIDEAで書くときに補完がよく効くようになる方法

結論

コメントを書く

具体的に

class Hoge
{
    /**
     * @return Fuga
     */
    public function createFuga()
    {
        return new Fuga();
    }
}

class Fuga
{
    /**
     * @var Piyo
     */
    private $piyo;
    
    public function __construct()
    {
        $this->piyo = new Piyo();
    }
    
    /**
     * @return Piyo
     */
    public function getPiyo()
    {
        return $this->piyo;
    }
    
}

class Piyo
{
...

みたいに書くだけ

そうすると下記のような状況で補完が効いて幸せになれます

$hoge = new Hoge();

// ここは別に何もしなくてもHogeのメソッドは補完の一覧に出てくる
$fuga = $hoge->createFuga();

// Hoge::createFuga に@returnコメントがないと
// 下記のようなコードを書く際に補完が効かない(getPiyoが一覧に出てこない)
$piyo = $fuga->getPiyo();

@return / @var 重要

Unitテスト書くときに少し幸せ

class HogeTest extends PHPUnit_Framework_TestCase
{
    public function testHoge()
    {
        $mock = $this->createMock();
        ...
    }
    
    /**
     * @return Hoge|PHPUnit_Framework_MockObject_MockObject
     */
    public function createMock()
    {
        return $this->getMock("Hoge", ...
    }
}

まあなんか上記の例は @depends を使ったほうが良いケースの場合もあると思うので書き方は臨機応変に…

1メソッドの中で、Mock作っちゃうとPHPUnit_Framework_MockObject_MockObjectとしてしか認識しないので、 当然Mock元のインスタンスメソッドとかは補完の対象として出てこないです。

上のようにあえて分離しといて@returnの内容を「|」で繋ぐと少し幸せになります

問題点

  • arrayとかの場合は全く幸せにならない
  • 幸せになるのはIntellij とか PHPStomeとかでPHP書く人だけっぽい
  • てか微妙に苦労するくらいなら端から別の言語で…

まさか「IDEAで楽したいから@return書け、絶対!」とか言えませんよね?

ってことでチーム内で強要(?)する場合は

  • PHPCS/MD に怒られないように丁寧にコード書こうね!
  • コメントはちゃんとココらへん見て書こうね!

とかすればいいんじゃないでしょうか。

まあゴミのような引き継ぎ案件でそれを途中から入れるのは無理だろうけど

なので新規なのにPHPを書かなければならない可哀想な方々、 導入時に静的解析ツールを入れましょう

まあ新規案件でPHPを選ぶとかあるのか…?






2012年12月16日日曜日

phpbrew + Template for Jenkins Jobs for PHP Projects 的なもの

そろそろPHP通算歴が半年くらいになっちゃうんじゃないかなぁ…

今や 継続インテグレーションは強みではなくなった [プログラマー現役続行] らしいですし、
PHPヤダヤダ言っててもしゃーないしで試してみました。

ていうか自動テスト環境すらないもの引き継がせんじゃねぇ糞が

ちなみに強引に動かしてます。


用意した環境
  • Cent0S6.3 64bit的な環境

主な参考サイト
Template for Jenkins Jobs for PHP Projects
c9s/phpbrew

Template for jenkins Jobs for PHP Project のリンク先に Integrating PHP Projects with Jenkinsなんて本がありますね。
2011/09 に出てたっぽいのですね。
うーむ、CIはもう常識なんですね、やばいなぁ…



jdkとかjenkinsはテキトーに入っている前提
jenkinsの導入はこの通りにyumで


phpbrew install

phpbrewのサイトのほぼ指示通りですね
Install phpbrew into system-wide environment の部分を参考にしています。
理由はjenkinsに無理やり使わせるためです

phpbrewで5.3.10を入れている理由は、phpbrew variants でサンプルで出てきたからという理由です。
皆さんお好きな環境でどうぞ。
+iconvしているのは、後々入れるphpmdやらphplocやらが使うからという理由です。
その他yumで入れているものは、カラの環境だと インストール時に怒られるから…という理由から入れています。

なお、自前でオプションを指定したい場合は「--」のあとに続けるとできます

phpbrew install

主に Install phpbrew into system-wide environment 参考

# phpが全く入っていないのはダメ

yum install php php-xml
yum install --enablerepo=rpmforge re2c libmhash

curl -O https://raw.github.com/c9s/phpbrew/master/phpbrew
chmod +x phpbrew
cp phpbrew /usr/bin/phpbrew

phpbrew init

#pythonbrewが入れてくれるやつをパクってみた

cat << _EOS_ >> /etc/profile.d/phpbrew.sh
#begin-phpbrew
if [ -n "${BASH_VERSION:-}" -o -n "${ZSH_VERSION:-}" ] ; then
    export PHPBREW_ROOT=/opt/phpbrew
    source /opt/phpbrew/bashrc
fi
#end-phpbrew
_EOS_

mkdir /opt/phpbrew
cp /root/.phpbrew/bashrc /opt/phpbrew/bashrc
source /etc/bashrc

yum install bison-devel bison libxml2-devel libxslt-devel

phpbrew install php-5.3.10 +default +iconv
# 自分でオプションを指定する場合は
# phpbrew install php-5.3.10 -- --with… みたいな

# 完了したら phpbrew switch/use php-5.3.10
# Dateの設定をしておく
vim /opt/phpbrew/php/php-5.3.13/etc/php.ini
[Date]
date.timezone = "Asia/Tokyo"

phpbrew use php-5.3.10

yum install autoconf
pecl install xdebug
phpbrew enable xdebug

# xdebug.iniを書き換える
vim /opt/phpbrew/php/php-5.3.10/var/db/xdebug.ini 

zend_extension=/opt/phpbrew/php/php-5.3.10/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so
view raw 2.md hosted with ❤ by GitHub



Template for Jenkins Jobs for PHP Projects とビミョーに違うところとか

まあ大体一緒です。
phpdoxじゃなくてphpdoc入れているところとかですかね。(ppwが作るやつがphpdoc使っているし)
あとppwでプロジェクト作るから…とかが差異だったりとか
その他plugin入れたり、テンプレートプロジェクトを入れたりとかは
同じことしているので省略

ビミョーに違うところ

Template for Jenkins Jobs for PHP Projects とビミョーに違うところ

pear config-set auto_discover 1
pear install pear.phpqatools.org/phpqatools 
# phpdoxじゃなくて http://www.phpdoc.org/ を入れた
pear channel-discover pear.phpdoc.org
pear install phpdoc/phpDocumentor-alpha

# php project wizardも必要なら入れておく
# https://github.com/sebastianbergmann/php-project-wizard
pear install phpunit/ppw
view raw 3.md hosted with ❤ by GitHub




jenkins先生に頑張っていただく

まずはプロジェクトを作ります。
テンプレがあるので楽ですね。
Template for Jenkins Jobs for PHP Projects 様様です

さて、Antを実行と見せかけて下記のようにします。
無理やりphpbrewを使うためです。
antもシェル上で叩いていますが、これを分離してしまうと
せっかく無理やり認識させたphpbrewが使えないからです。
うーむ無理やりw
なお、使用しているAntはJenkins先生が自分でインストールしてくる奴のパスを叩いています。
一度はAntタスクを実行しないとインストールされませんので、その辺は適当に。

export PHPBREW_ROOT=/opt/phpbrew
source /opt/phpbrew/bashrc
phpbrew use php-5.3.10
$JENKINS_HOME/tools/Ant/1.8.4/bin/ant


publish HTML report もほんのちょびっとだけいじります
index.xhtml → index.html にするだけ。
実際上記の通り作ると、build/api 以下にそう作られていたから…以上の意味は無いです。




準備ができたらppwでプロジェクトを作ります。
別に自前でant用のbuild.xml書いてもいいですけど、メンドイですよね。

他にもMave for phpなんてのもあるし、
そもそも時代はGradleらしいです。
Ant使っている場合じゃねぇ(AAry

そこはとりあえず置いといて…

ppwがデフォルトで作成してくれる状態に超テキトーにソースを加えたものを実行してみました。
ここに置いときます


テストは通ってないし、警告は出るしで最低ですねw
常にJenkins先生を怒らせないような状態を保つようにすれば、
もしかしたらPHPもゴミクズのように言われない日が来るかもしれませんね。







まあそんな日は来ないだろうけどな