山pの楽しいお勉強生活

勉強の成果を垂れ流していきます

WindowsでJVM言語「Golo」を使ってみた。

はじめに

JVM上で実行できる動的言語「Golo 2.0」リリース という記事を今更ながらしって、どんなんだろう?っとググったけど、試してる人すらみつからなかったので試してみる。

  • The Golo Programming Languageの最初を適当に実行しています。
  • 最初のみなのでGolo独自機能などは触っていません。
  • ほぼコードしか読んでいません。そもそもあめりか語は殆どわからないので、間違っていたら指摘してください。
  • ごろー

インストール

c:\>cd c:\work\20150211\golo-2.0.0\bin
c:\work\20150211\golo-2.0.0\bin>golo version
2.0.0

HelloWorld

直接ファイルから実行

  • 公式にでかでかと乗っているHelloWorldをコピーして、helloworld.goloとして保存。(拡張子は適当。)
module hello.World

function main = |args| { 
  println("Hello world")
}
  • golo golo --files ${ファイルPATH}」で実行。
c:\work\20150211>golo-2.0.0\bin\golo golo --files ./helloword.golo
Hello world
  • もし、引数を渡したい場合には「--args」をつけるらしい
  • コード
module hello.World

function main = |args| {
  foreach arg in args {
    println(arg)
  }
}
  • 実行
c:\work\20150211>golo-2.0.0\bin\golo golo --files ./hellowordWithArgs.golo --args hello world hoge huga
hello
world
hoge
huga

コンパイルして実行

  • コンパイル(--output付けることでディレクトリを指定。)
c:\work\20150211>golo-2.0.0\bin\golo compile --output classes helloword.golo
  • 実行。
c:\work\20150211>cd classes
c:\work\20150211\classes>..\golo-2.0.0\bin\golo run --module hello.World
Hello world

変数

  • letvarがある。
    • letは固定値。
    • varは再導入可能な変数。
  • コンパイルエラー
module hoge

function main = |args| {
  let h = 1
  println(h)
  h = 2
  println(h)
}
c:\work\20150211>golo-2.0.0\bin\golo golo --files ./hoge.golo
[error] In Golo module: hoge.golo
[error] Assigning `h` at {line=6, column=3} but it is a constant reference
module hoge

function main = |args| {
  var h = 1
  println(h)
  h = 2
  println(h)
}
  • intStringで型指定を試してみたけど型は指定できないみたい。
module hoge

function main = |args| {
  int h = 1
  println(h)
}
c:\work\20150211>golo-2.0.0\bin\golo golo --files ./hoge.golo
[error] In Golo module: hoge.golo
[error] Assigning to either a parameter or an undeclared reference `h` at (line=4, column=7)
[error] Undeclared reference `int` at {line=4, column=3}
[error] Undeclared reference `h` at {line=5, column=11}

  • Javaの型は普通に使えるみたい。
  • Collectionは結構面白い。
  • コード
module hoge

function main = |args| {
  var tuple = [1, 2, 3] # gololang.Tuple
  println("tuple : " + tuple)
  var array = array[1, 2, 3] # Object[]
  println("array : " + array)
  var list = list[1, 2, 3] # LinkedList
  println("list : " + list)
  var vector = vector[1, 2, 3] # ArrayList
  println("vector : " + vector)
  var set = set[1, 2, 3] # LinkedHashSet
  println("set : " + set)
  var map = map[[1, "a"], [2, "b"]] # LinkedHashMap
  println("map : " + map)
  var range = [1..10] # gololang.Range
  println("range : " + range)
}
  • 実行結果
c:\work\20150211>golo-2.0.0\bin\golo golo --files ./hoge.golo
tuple : tuple[1, 2, 3]
array : [Ljava.lang.Object;@5b0a1d2d
list : [1, 2, 3]
vector : [1, 2, 3]
set : [1, 2, 3]
map : {1=a, 2=b}
range : range(1,10)

コメント

  • 行コメントは//ではなくて#
  • ドキュメントコメントは----で囲えばいいらしい。
    • マークダウンで書くといいって書いてあるけど、Document生成した時いい感じにしてくれるのかな?

関数定義

  • listに対してfilterとかmapとかで関数を渡すことが可能。
module hoge

function main = |args| {
  println(list[1, 2, 3, 4]: filter(|n| -> (n % 2) == 0)) # [2, 4]
  println(list[1, 2, 3]: map(|n| -> n * 10)) # [10, 20, 30]
}
  • 関数の合成も可能。
module hoge
function main = |args| {
  let f = |x| -> x + 1
  let g = |y| -> y * 10
  let h = f: andThen(g)
  println(h(1)) # (1 + 1) *10 = 20

  let adder = |x, y| -> x - y
  let add2 = adder: bindAt(1, 2)    # adderのyに2を設定
  println(add2(5)) # 5 - 2 = 3
}

EasyMockでvoidメソッドの振る舞いを定義する方法。

EasyMockで普通のメソッドと同じようにvoidのメソッドの振る舞いを定義しようとしたらハマったのでメモ。(いくつか情報は出たものの、意味がわかりづらかった。)

回答

  • 普通のメソッドのように定義すると「EasyMock のメソッド expect(T) は引数 (void) に適用できません」とエラーになります。
  • よって、一度振る舞いを定義したいメソッドを呼び出した後に「expectLastCall()」を呼ぶことでその呼出を記録することができます。
  • 詳細は以下のサンプル参照。
    • 比較用にvoid以外のメソッドの振る舞いも同時に定義しています。
// テスト対象クラス
public class Hoge {
        // 返り値がString
    public String methodA() {
        return "methodA";
    }

        // 返り値がvoid
    public void methodB(String str) {
    }
}

// テストクラス
public static class HogeTest {
    @Test
    public void testMethod() throws Exception {
        Hoge hogeMock = createMock(Hoge.class);

                // 返り値がStringの場合。
        expect(hogeMock.methodA()).andReturn("mockMethodA"); 

                // 返り値がvoidの場合。
        hogeMock.methodB("str"); // 一回処理を呼び出す。
        EasyMock.expectLastCall(); // 一つ前の挙動を記録する。

        replay(hogeMock);

        assertThat(hogeMock.methodA(), is("mockMethodA"));
        hogeMock.methodB("str"); // str以外の値の場合に例外。

        verify(hogeMock);
    }
}

※上記例はEasyMock Class Extensionが入っている状態での例になります。(使用しないとインターフェースのみ。)

参考

2014年の反省

2014年もそろそろ残りが少なくなってきました。 っということで、2014年の目標の達成度と反省をしようかと。

2014年の目標と結果

勉強会に参加したらblogを書く

  • 今年は9回の勉強会に参加して、8回のblogを書きました。
  • 書いていない1回は11月末のJavaFX勉強会以外は全て記載。
  • JavaFX勉強会はプライベートと仕事共に忙しい時期でいっぱいいっぱいだったのですが、メモはとっていたので少しでも時間見つけて書くべきだったと反省。
  • その他の書いた記事もメモレベルでしか書けていないので、今後はもう少し見れる形で公開するようにしたいです。
  • ただ、去年1年では46記事も書けていたので、blogを書く習慣をつけるというサブ目標はほぼ達成に近いかなと。
  • 良い習慣なので、来年も継続していきたいですな。

Gitを日常的に使う

  • 会社でGitLab導入中で、社内ハッカソンでGitHubを使用というのが実績か。
  • 正直日常的とは言いがたいが、通常操作位はなんとか出来るくらいまでは出来たかなという印象。
  • 来年はGitLabを運用に乗せて行くので、来年いっぱいでは日常的に使っているようになるはず。。。

目標以外の成果

総括

  • 目標は必ず達成できるレベルで設定しているのに、これは残念な結果。後、一押しが足りない。
  • 目標以外もイマイチ。
  • ただ、個人的には今年はよく頑張った感があるのが不思議。
  • 来年も目標はたてるので、しっかりと最後まで意識していきたい。

git-svnでOut of memoryが出て困ったのでsmartgit使って解決した話。

概要

  • git-svnで少し楽になろうと思ったらOut of memoryが出てわけわかめになったという話。
  • 結局git-svn、SourceTreeでは解決できず。
  • smartgitを使用することでローカルにgitリポジトリが作れました。

環境

Windows 7 Professional git version 1.9.4.msysgit.2

事象

  • コマンド
$ mkdir svngit
$ cd svngit
$ git svn init -s --prefix=svn/ https://xxx/yyy
$ git svn fetch -r 50000:HEAD
  • 出力
    • hogehoge.sql は当然、こんなに大きなサイズではありません。
(略)
        A       hoge/huga/piyo/hogehoge.sql
Out of memory during request for 156 bytes, total sbrk() is 251326464 bytes!

解決方法

  • 概要でも書きましたが、smartgitを使用することで解決。

  • ↓のコメントが決め手になりました。(引用元

    単体でもすぐれたGUIクライアントなのですが、SVN連携にはgit-svnより強力な連携機構を独自実装しているのでこちらならエラーなく取り込めるかもしれません。

  • smartgitのインストール、設定などは特に問題ないかと思いますが、ここが参考になりそうです。

解析(予想)

  • 使用しようとしているリポジトリのファイルを全て合わせると数ギガとかなりでかい事が原因か。
  • git内で使用されているperl内で発生してるっぽい。
    • タスクマネージャで見ててもperlのメモリが256M位になると発生する。
  • 以下のスクリプトで発生してるっぽい。
    • 「$read」にファイル読んで入れてる所が原因?
C:\Program Files (x86)\git\lib\perl5\site_perl\Git\SVN.pm
  • 「sbrk()」はCの関数らしい

試したこと

  • .git/config の編集。
    • メモリの設定項目を適当に上げてみた。
[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
    hideDotFiles = dotGitOnly
    packedGitWindowSize = 1024m
    packedGitLimit = 1024m
[pack]
    threads = 2
    windowMemory = 1024m
    deltaCacheSize = 512m
    packSizeLimit = 1024m
[svn-remote "svn"]
    url = https://xxx/yyy
    fetch = hoge/huga/trunk:refs/remotes/svn/trunk
    branches = hoge/huga/branches/*:refs/remotes/svn/*
    tags = hoge/huga/tags/*:refs/remotes/svn/tags/*

参考URL

ハチイチ忘年会に参加してきた。 #1981s

ハチイチ忘年会って何?

ハチイチ忘年会は 1981年生 のWeb・IT系エンジニアの人達が「 幹事をする 」 忘年会です。

概要

毎年年末恒例のハチイチ忘年会に参加してきました。 2011年、2013年に続いて3回目の参加でしたが、毎回生きててよかったと思う位楽しいので、今年も楽しみにしていました。

で、やっぱり楽しすぎる位楽しかった。 来年も必ず参加する!

開催前

  • 会社の人誘ったけど全然釣れない。。。
  • 前職の人やら、友人を誘ったけど誰も釣れず。

  • 嫁から2次会の許可を得るために頑張る。

やった事とか話した事とかあった事とか。

  • 知らない人と話すのは緊張するから酒を飲む → 飲み過ぎる → 何話したか忘れる → 誰と話したかすら覚えてない
    • みんな同じこと思ってて安心した。
  • さくらインターネットのデータセンターツアーについてで盛り上がる。
  • 同僚とかを勉強会に誘う方法。
    • いつも皆様に聞いてる事。
    • 飲みに誘って、飲む前に少し参加しようぜ?って誘い方はどうかと言われて納得。次使ってみる。
  • 楽しそう。

  • Chrome作ってる人がいた。

    • 日本人もいるのか。。。
    • しかも2人来ていたらしい。
  • なんか友人が出来た。
    • 今度飲みましょう。
  • 話し込んでたら嫁との約束時間に遅れる。

終了後

  • 普段1時間弱で帰れるはずなのに2時間かけて帰宅。
    • 覚えてない。
  • おうちから締め出される。
  • 嫁に4時まで説教されました。

まとめ

  • 今年も最高に楽しかった。
  • やっぱり顔とか名前を覚えていない。
  • 逆に話した人も私の事も覚えていないと思われる。
    • 来年は名刺作って配る。
    • そうじゃなくても、首から下げとく。
  • 時間は守る。
  • お酒はほどほどに。

301リダイレクト(恒久的な移転)は一度リダイレクトされると、その後にコンテンツができていてもリダイレクトされる。

概要

サーバが301リダイレクトを返してきた場合、ブラウザはリダイレクト先のURLをキャッシュして、次に元のURLにアクセスした際には直接リダイレクト先のURLにアクセスする。

  • 元URLにアクセスしないので、現在はコンテンツがあっても考慮されない!
  • この現象自体を知らないと原因究明が出来なくてハマる。っていうかハマった。

  1. http://example.com/hoge」にアクセス。
  2. 301が返ってきて「http://example.com/piyo」にリダイレクト。
  3. http://example.com/hoge」にアクセス。
  4. http://example.com/hoge」にアクセスすることなく「http://example.com/piyo」が表示。

解決方法

  • この状態になってしまったらブラウザのキャッシュ削除。
  • 301はあくまでも恒久的な移転。用途によって302(コンテンツが存在するけど移動する)、306(将来のための予約)、307(一時的な移転)などを使用すべき。

参考URL

SVN(TortoiseSVN)で特定のリビジョンのファイルをコピーしたい

やりたいこと

  • hoge.txtというファイルの過去のリビジョンをpiyo.txtという名前でコピーしたい。

SVNのコマンドを使用する場合

  • svn copy -r revision src dstで可能。
  • svn copyのリファレンス
  • ↑のコマンド例。(リビジョン8のbat.cをya-old-bat.cとしてコピー。)

    $ svn cp -r 8 bat.c ya-old-bat.c A ya-old-bat.c

TotoiseSVNを使用する場合

  • コピー元のファイルのログを開く。
    • 右クリック → TotoiseSVN → ログを表示
  • コピーしたいリビジョンを右クリック。
  • 「このリビジョンからブランチ/タグを作成」を選択。
  • 宛先パスにコピー先を入力。
  • ログメッセージを入力。
  • OK。

備考とか

  • コピーしたファイルのログをTortoiseSVNで見る場合は、「コピー/名前変更が発生したら停止」のチェックを外す必要がある。
  • SVNではブランチやタグはコピーということは知っていたけど、ファイルでブランチ、タグを切るというのは違和感あり。