ページ

2012年12月30日日曜日

[Blogger] Chromeで Syntax Highlighter のレイアウトが崩れる

少し前に (2012/11頃)、Chrome で Syntax Highlighter のレイアウト が崩れる現象が起きて、 回避策を導入していたのでそのメモ。 発生していた症状は以下の2つ。
  • 2ケタ以上の行番号が1文字づつに改行されてしまう。
    行番号として機能していない状態になっている。
  • ソースコード側に予期しない改行が入ってしまうのだが行番号が増えない。
    結果として行番号がずれたり、後ろの方に行番号のない行ができたりする。
しばらく回避策を入れて様子を見てみたのだが最近は復旧しているようなので、 回避策を除去するついでに導入していた回避策をメモしておく。

2012年12月29日土曜日

[Blogger] Syntax Highlighter V3 に枠をつけたりとか。

前回の記事で、HTML/JavaScript ガジェットで Syntax Highlighter を設置するところまでできた。 Syntax Highlighter を設置した時はテーマに Midnight を選択していたが、ちょっとキツイのでデフォルトに戻すことにした。 だが、ページ背景が白で、Syntax Highlighter の背景も白なのでコード部分が目立たないというか境界がわからなくなってしまう。
そこでコード部分に枠をつけてみることにする。

2012年12月23日日曜日

[Blogger] Syntax Highlighter V3 を JavaScript ガジェットで設置

Syntax Highlighter 導入メモ第三弾。

前回、テンプレート HTML を直接編集するのを嫌って、CSS カスタマイズで Syntax Highlighter を導入しようとしたがあえなく失敗した。
今度は、JavaScript ガジェットでやってみたところうまくいったのでそのメモ。

基本的には CSS のロードさえ JavaScript の中からできればうまくいくはず。
ここのコードを参考にさせてもらった。

2012年12月1日土曜日

[Blogger] Syntax Highlighter V3 を CSS追加から導入

前回、Syntax Highlighter V3 を導入してみた。 これはこれでうまく動作したのだが、テンプレート HTML を編集する必要がある。

あまり、テンプレート HTML をいじりすぎるとどこをどういじったかわからなくなるので、 なるべくテンプレートをいじりたくはない。

そこで、テンプレート カスタマイズの 「CSSを追加」で行けるか試してみた。
・・・ が、あえなく敗退。
今回はその敗退の記録。

2012年11月24日土曜日

[Blogger] Syntax Highlighter V3 を導入する

このブログでは Source コードを載せることが多いのだが、 キーワードのハイライトができる Script があったので導入してみる。
Blogger に導入する際に参考にしたのはこちら。 このページで 「 GENERATE SCRIPTS 」をすると、Blogger 用のスクリプトが生成されるので、 Blogger の HTML の編集で「 </head> 」タグの直前に貼り付ける。

今、貼り付けているコードはこんな感じ。
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeMidnight.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script language='javascript' type='text/javascript'>
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.all();
</script>
「 shThemeMidnight.css 」のところは使うテーマによって変わる。ファイル名の形式は「 shTheme<テーマ名>.css」。テーマは以下で Preview できる。
ハイライトする言語ごとに必要な JavaScript ファイルをロードする。
上の例では、 JavaScript, Java, PlainText, Scala, Xml(HTML) をロードしている。
使える言語と、記事中で指定する言語Alias、ロードするファイル名の一覧は、 に一覧されている。



記事の中で Syntax Highlighter を使うには、
<pre class="brush: html">
[ ここに ハイライトされるコードを書く ]
</pre>
を挿入する。
コード中の 「 < 」、「 > 」などは実体参照でエンコードする必要がある。 エンコードしないでも動いていたりするが、HTML 的に気持ち悪いし、本家でもエンコードしろと書いてあるのでエンコードして貼り付けている。

他にも、script タグ + CDATA で書く方法もあり、エンコードが不要などメリットもあるのだが、記事の内容が Script の一部として記載されるのはさすがに気持ち悪いので pre 方式を採用。
具体的な方法は、 を参照。

2012年11月15日木曜日

[AppEngine] jdoconfig のパラメータ

AppEngine の Eclipse プラグインでプロジェクトを作成すると、JDO 用の設定ファイルである jdoconfig.xml が作成される。
その中に、

<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="false"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" 
             value="true"/>

というパラメータがある。 JDO のドキュメント によると意味は以下の通り。

パラメータ意味
NontransactionalReadWhether to allow nontransactional reads
NontransactionalWriteWhether to allow nontransactional writes
RetainValuesWhether to suppress the clearing of values from persistent instances on transaction completion

autoCreateDatastoreTxns は JDO で規定されているパラメータではなく App Engine 固有の設定なので、 App Engine のトランザクションの説明 に記載されている。
false にすると JDO 的にトランザクションを有効にしても データストアのトランザクションは起動しないらしい。

実際に試してみよう。

2012年11月13日火曜日

[AppEngine] データ更新時の Index の使用量

この間、JDO でデータを挿入・削除した場合、それぞれ
キー以外の属性数×2 + 1」回のインデックス書き込みが発生した。

念のため、JDO で属性を一つだけ更新した場合のインデックス書き込みの回数を見てみよう。
予想としては、1属性で2つのインデックスがあるから2回発生するはず。

まずデータひとつ作成
MyData data = new MyData();
data.setName("one");
data.setName2("two");
data.setNo(10L);
pm.makePersistent(data);

ResourceDaily Quota
Datastore Entity Put Ops 0 → 1
Datastore Index Write Ops 0 → 7

キー以外の属性は3つなので想定通り 7 Index Write Ops。

2012年11月5日月曜日

ツェラーの公式:曜日を計算する

年月日が与えられたときに、その曜日を計算する公式として「ツェラーの公式 (Zeller's Congruence)」がある。

Wikipedia によると、
ツェラーの公式(Zeller's congruence)とは西暦の年、月、日からその日が何曜日であるかを算出する公式である。 まず求めたい日の年の千の位と百の位の連続の数字(例えば2310年ならば23)をJ、年の下2桁(例えば2310年ならば10)をK、月をm、日をq、曜日をhとする。ただし求めたい日の月が1月、2月の場合はそれぞれ前年の13月、14月とする(例えば、2007年1月1日なら2006年13月1日とする)。


hが0なら土曜日、1なら日曜日、2なら月曜日、3なら火曜日、4なら水曜日、5なら木曜日、6なら金曜日である。
とのことらしい。
はガウスの記号で、x を超えない最大の整数(小数点以下切り捨て)を表す。
この記事では、以下 [ x ] で表すことにする。

2012年10月18日木曜日

[Scala] JSON の標準パーサーで数値型が Double になる問題への対処方法

前回、Scala の JSON 標準ライブラリを使ってみた。 Scala の 標準パーサーでは、数値型が常に Double として扱われてしまう問題がある。
  val text = """{ "x":1 }""";
  val result = JSON.parseFull(text);
  val map = result.get.asInstanceOf[Map[String, Option[Any]]];
  println (map.get("x").get);

--------------------
1.0

2012年10月14日日曜日

[Scala] JSON の扱い

Scala には 標準で JSON を扱うためのクラスが用意されている。
sjson というライブラリもあるが、 まずは Scala 標準の JSON を使ってみる。


パース

scala.util.parsing.json.JSON クラスを使ってテキストの JSON をパースする。
  • JSON.parseRaw
    パース結果として、Option[JSONType] が返る。
  • JSON.parseFull
    パース結果として、Option[Any] が返る。
他に JSON.parse というメソッドもあるが、Scala 2.8.0 以降は Deprecated されて parseRaw または parseFull を使うようになっている。

2012年10月8日月曜日

[Blogger] Zenbackを設置してみる。

Blog でよく見かける「関連記事」。Blogger にもあんなのがあるといいなぁ、と思っていたのだが Zenback というサービスのものがよさげだったので設置してみることにした。

参考にしたのはここ。

Zenback サイトでの登録


以下、実施ログ。

まずは、Zenback サイトでアカウント作成とブログの登録登録。
  1. Zenback のサイトで 「新規登録&コードを取得する」。
  2. メールアドレスと Zenback ログイン用のパスワードを指定。
  3. Blog の URLを入力する。
  4. 表示したい項目を指定。
    ソーシャルボタン、関連する記事、関連するみんなの記事(必須)、Twitter での反応、
    はてなブックマークでの反応、Facebook コメントがある。
    Twitter のパスワードもここで指定する。
    デフォルトでは全部ついているのでとりあえずそのまま。
    不要ならきっとあとで外せるだろう。Twitter のパスワードは未入力のまま。
  5. ブログに張り付けるためのスクリプトが出力される。

出力されたスクリプトはこんな感じ。

<!-- X:S ZenBackWidget --><script type="text/javascript">document.write(unescape("%3Cscript")+" src='http://widget.zenback.jp/?base_uri=http%3A//xawa99.blogspot.jp/&nsid=107166696824918689%3A%3A107166812789038893&rand="+Math.ceil((new Date()*1)*Math.random())+"' type='text/javascript'"+unescape("%3E%3C/script%3E"));</script><!-- X:E ZenBackWidget -->



Zenback の管理画面


スクリプトコードを取得すると、Zenback の管理画面に遷移する。
ここでは、挿入するスクリプトの再表示やウィジェットのテーマ、表示する項目、ソーシャルボタン、関連する記事の表示設定が選べる。

関連する記事の表示設定では「サムネール付き」と「テキストのみ」が選べる。
このブログの記事はどこもテキストだらけで代わり映えがしないのでサムネールをつける意味は全くないのだが、とりあえずはデフォルトのサムネールつきのままにしておこう。あとで変える。


ブログにスクリプトを挿入する。


Blogger の管理画面の「レイアウト」で、好きな場所でガジェットの追加をして「HTML/JavaScript」ガジェットを追加する。
そのコンテンツとして先ほどの Script をペースト。HTML の編集をしないで済むので簡単でいい。

表示してみる。

「関連する記事」や「関連するみんなの記事」には「表示されるまで数分〜最大で数日ほどかかります。しばらくお待ちください。」と表示される。
Zenback ブログによると、
zenbackのコードを貼ってから、「関連記事」「関連リンク」が表示されるまで、数時間~最大30時間ほどかかる場合があります。ご了承ください。
ということらしい。
何日かするとこの部分に関連する記事が表示されるようになる。大体2~3日はかかるみたい。
ガジェットを張り付けた位置に、「zenback読み込み中です。」が表示されたままになる場合には Script が間違っている可能性があるので要確認。

一時期、Zenback にブログを登録した直後に表示される Blogger 用の Script が間違っていたらしいので、 その場合には、Zenback の 管理画面から再度 Script を取得しなおして貼りなおす。


テンプレートカスタマイズ


「HTML/JavaScript ガジェット」 だとトップページを含めすべての画面に関連記事一覧が表示される。
関連記事という性格上、個別記事ページだけでよいのだが残念ながらそうはいかない。

個別記事ページのみにする場合には テンプレートをカスタマイズする必要がある。
swordsmith ブログにそのあたりが詳しく記載されているので、気が向いたらそのうちやってみよう。

2012年10月7日日曜日

[Blogger] 行間を開ける

Blogger を使っていて思うのは微妙に行間が狭いということ。
レイアウトやテンプレートデザイナーの設定にもないので、テンプレートを直接編集しないといけないのかな、と思っていたら、CSS を設定するだけの簡単な方法があった。

2012年10月5日金曜日

Eclipse に インポート時に Unsupported IClasspathEntry が出る

Eclipse + m2e 環境で プロジェクトをインポートすると

An internal error occurred during: "Importing Maven projects".
Unsupported IClasspathEntry kind=4

となることがある。

自分の場合は pom.xml から mvn eclipse:eclipse で生成したScala プロジェクトを、 「 Existing Maven Projects 」で import したときに発生した。

2012年9月30日日曜日

[Scala] Eclipse に Scala の Maven プロジェクトを インポート。の続き

前回、m2eclipse-scalaを使って、Scala プロジェクトの pom.xml を Eclipse にインポートした。
インポートの結果作成された .project ファイルと、.classpath ファイルの中身を確認しておく。

2012年9月28日金曜日

[Scala] Eclipse に Scala の Maven プロジェクトを インポート

Eclipse に Scala の Maven プロジェクトを m2e を使ってインポートする。

m2eclipse-scala を使う。
これをインストールしておかないと、pom.xml を import するときに、 maven-scala-plugin:2.15.2:compile と testCompile の resolve ができずにエラーになってしまう。


2012年9月26日水曜日

[Scala] REPLを使う

これまで Scala は Eclipse IDE で使ってきた。
Eclipse IDE で使う分には Scala SDK のインストールは必要ないのでインストールしていなかったのだが、 ちょっとしたことを確認するのに REPL があると便利なので入れてみる。

Scala の本家 から最新の stable release である Scala 2.9.2 をダウンロード。
Windows 版は zip 版と msi 版があるが msi 版は何がどう設置されるのかわからないので zip 版をダウンロード。 展開して bin ディレクトリにパスを通す。

これだけで準備は完了。REPL を使ってみる。

2012年9月24日月曜日

Sakura エディタ で HTML エンコードマクロを作る。

Blogger で XML ソースを書く際には 特殊文字をエンコードする必要があるのだが、面倒なのでエディタで一括で処理できるようにしよう。普段はサクラエディタ (Sakura Editor) を使っているので、サクラエディタのマクロとして作ることにする。

2012年9月23日日曜日

[Scala] match 文の仕組み

このブログを見て match 文 の仕組みが分かった気がするのでメモしておく。
List のマッチでは case List(x,y) みたいな形式だったので気が付かなかったのだが、 case 句には オブジェクトも書くことができる。

2012年9月21日金曜日

[Scala] 正規表現によるマッチ

正規表現を使った match ... case 文を使ってみる。

val p : Regex = ".*no=([0-9]+),name=(.*)".r;
val values = List(
  "no=10,name=ten",
  "no=11,name=eleven",
  "no=20,name=twelve" );

for (value <- values ) {
  value match {
    case p("10", v) => println("name for 10: " + v)
    case p("11", v) => println("name for 11: " + v)
    case p(n, v) => println("name, value= " + (n,v))
  } 
}

name for 10: ten name for 11: eleven name, value= (20,twelve)

2012年9月20日木曜日

[Scala] 一般クラスのマッチ

List や Tuple ではない一般のクラスの場合、unapply、unapplySeq いわゆる抽出子(extractor)を定義しておくことで match ... case 文で使えるようになる。

...
  val a = new MatchSampleClass;
  a match {
    case MatchSampleClass(x, y) => 
      println("x: " + x + " y: " + y);
    case _ => println("OTHER: " + a);
  }
....

class MatchSampleClass
object MatchSampleClass {
  def unapply(obj : MatchSampleClass) : Option[(String, String)] = {
    return Option(("ONE", "TWO"));
  }
}

x: ONE y: TWO

2012年9月18日火曜日

[Scala] Eclipse の Java プロジェクトで Scala を使えるようにする。

目標: 既存の Java プロジェクトで Scala も使えるようにすること。

基本的には、.project ファイルと .classpath ファイルに手を入れればできるはず。
やってみよう。

前提条件は、Eclipse に Scala IDE が導入されていること。
環境は、Eclipse Juno + Scala IDE nightly build 版( Juno 対応版)。

.project や .classpath ファイルを直接編集するので、Eclipse は終了しておくか編集対象プロジェクトを Close しておく。

2012年9月17日月曜日

[Scala] Maven2 で Scala を使う。

Mavan2 を使って Scala をビルドできるようにしておこう。
Maven-scala-Plugin を使う。
主な情報源は以下の2つ。
基本的に必要な情報はだいたいこの2つにある。

Maven-scala-Plugin の 最新版は 2.14.2-SNAPSHOT、最終更新は 2010-08-04 15:42 と記載されているが、 実際にリポジトリ上には現時点で 2.15.2(Sun Feb 06 08:52:23 CST 2011) がアップロードされている。

2012年9月16日日曜日

m2e で Eclipse + Maven 環境を作る時に J2SE を指定する

これまで、 の両記事で m2e での import の動作についてみてきた。
m2e で pom.xml をインポートする際に、

Build path specifies execution environment J2SE-1.5. 
There are no JREs installed in the workspace that are strictly compatible with this environment.

という警告が出ていたのだが、これは pom.xml に maven-compiler-plugin の configuration を書くことで抑止できる。
やってみる。

2012年9月15日土曜日

m2e で Eclipse + Maven 環境を作る。の続き

前回、m2e で Eclipse + Maven 環境を作成した。
Eclipse に インポートした際に作成される .project や .classpath の中身を確認しておこう。

2012年9月14日金曜日

m2e で Eclipse + Maven 環境を作る。

以前は、Eclipse + maven といえば、 m2eclipse プラグインMだったが、 最近は Eclipse プロジェクトに統合されて m2e となっている。 m2e で maven プロジェクトを Eclipse に取り込んでみる。

2012年9月11日火曜日

[Scala] シーケンスのマッチ

List などシーケンス(Seq)のマッチを見てみよう。
Tuple と同様に型や出現位置によってマッチングを行い、変数への値の設定が行われる。
Tuple と違って List は可変長なので各 case 句の要素数の違いによるマッチもできる。

2012年9月9日日曜日

[Scala] 後のオブジェクトのメソッドが実行される演算子

Scala では 「:(コロン)で終わる演算子」 を中置記法で使うと 「後のオブジェクトのメソッド」 が実行される。代表的な例が、List#:: 。

val aList = List("A");
println (aList.::("x")); 
println ("x" :: aList);

List(x, A) List(x, A)

「 aList.::("x") 」では普通のメソッドと同様に aList の :: メソッドが実行される。
「"x" :: aList 」と中置記法で書くと、通常は演算子の前のオブジェクトがレシーバーになるのと違い、 演算子の後にある aList がレシーバーになる。

2012年9月7日金曜日

[Scala] match (Tuple編)

Tuple に対する match...case のパターンマッチを見てみる。これがかなりに強力。
引数の型や数によってマッチする case 節を判定し、マッチした case 節の変数に値を割り当ててくれる。

val list1 : List[Any] = List(
    ("one", 1), (2, 2), ("three", "tri", 3) );

for (elem <- list1) {
  elem match {
    case (v1: String, v2:Int) => 
        println("[String, Int]: " + v1 + ", " + v2);
    case (v1: Int, v2:Int) => 
        println("[Int, Int]: " + v1 + ", " + v2);
    case (v1, v2, v3) => 
        println("[Triple]: " + v1 + ", " + v2 + ", " + v3);
    case _ => println("OTHER");
  }
}

[String, Int]: one, 1 [Int, Int]: 2, 2 [Triple]: three, tri, 3

2012年9月6日木曜日

[Scala] match (基本編)

多彩な機能を持つ Scala のMatch 文を見ていくことにする。

まずは基本形。

val a : Int = 2;
a match {
  case 1 => println("ONE");
  case 2 => println("TWO");
  case _ => println("OTHER: " + a);
}

いずれの条件にもマッチしなかった場合、Java でいうところの default は 「case _ 」で書く。

2012年9月5日水曜日

[AppEngine] ログ出力

Google App Engine ではファイル出力ができないので、 何か記録を残そうとしたらデータベースに書くかログに出力することになる。
App Engine ではデフォルトでは java.util.logging を使用する設定になっている。

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException, ServletException  {

        Logger logger = Logger.getLogger("SampleLogger");
        logger.info("INFOログです。");
        logger.warning("WARNINGログです。");
        resp.setContentType("text/plain; charset=utf-8");
        resp.getWriter().println("ログ出力テスト");
    }

管理ツールのLogsで見るとこんな感じに出力されている。

管理ツールのLogs画面で Timezone を選択できる。ログの時刻はここで選択した Timezone を使って表示される。

2012年9月4日火曜日

[AppEngine] JDO の Cross-Group-Transaction

AppEngine のデータストアでは、デフォルトではトランザクションの中で複数のエンティティグループにまたがる変更を行うことはできない。
複数のエンティティグループにまたがるトランザクションを実行するには、クロス グループ トランザクションが必要になる。今回はこのクロス グループ トランザクションを試してみる。

2012年9月3日月曜日

[AppEngine] JDO のトランザクション

JDOでのトランザクションの基本。

PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction tx = null;
try {
    tx = pm.currentTransaction();
    tx.begin();
    MyData data = new MyData();
    data.setName("one");
    pm.makePersistent(data);
    tx.commit();
} finally {
    if ( tx != null && tx.isActive() ) {
        tx.rollback();
    }
    if ( pm !=null && ! pm.isClosed()) {
        pm.close();
    };
}

2012年9月2日日曜日

[AppEngine] データストアの Quota と Index

前回、調子に乗ってデータストアのテストをしていたらあっという間に、無料分の Quota の制限に達してしまった。 AppEngine 管理コンソールで詳しく見てみる。

「Quota Details」 画面で見てみると、引っかかったのは「Datastore Write Operations」 の 「0.05 Million Ops / 24 hour」。

2012年9月1日土曜日

[AppEngine] Eventual ということ。

前回の記事で、データの追加、削除、更新、取得をやってみた。
一応動くのだが、たまに表示される結果にデータの変更内容が反映されていないことがある。

Google App Engine のデータストアの形式には以前は、「Master/Slave」形式と「High Replication」形式があったのだが、「Master/Slave」形式は廃止されて、現在はアプリケーションを作成する際には「High Replication」しか選択できないようになっている。
「High Replication」ではデータの取得が eventual である、すなわり取得したデータが最新ではない可能性があるとのこと。どうやらそのせいのようだ。

2012年8月31日金曜日

[Scala] getter / setter

Scala ではメンバ変数の定義や初期化を簡単に記述することができる。

object PropSample {
 def main(args: Array[String]) : Unit = {
    val d : Data = new Data(100);
    println(d.value);
    d.value = 200;
    println(d.value);
  }
}
class Data(var value : Int)
100 200

クラス定義はこの一行で、public なメンバ変数 x の定義( Scala では、可視性修飾子がない場合は public )と、コンストラクターによる初期化が自動的に定義されている。

この時、内部的には private なフィールドと名前 x のアクセッサが生成されているのだが、Scala 的に見た場合には public メンバ変数へ直接アクセスしているということになる。

2012年8月29日水曜日

[ドリトル] ドリトルのマウス

ドリトルでマウスの現在座標は Screen オブジェクトに対する xPosition?yPoistion? で取得する。
mouseMoved のようなマウスが動いたときに発生するイベントのようなものはないので、基本的には タイマーやほかのオブジェクトのイベント実行時に、その時点でのマウス座標を取得するという形式で利用する。

// create axes
t1 = Turtle ! create.
t1 ! 1 linewidth (red) linecolor.
t1 ! penup -1000 -1000 moveto pendown.
xLine = t1 ! 1000 -1000 moveto makeFigure.
t1 ! penup -1000 -1000 moveto pendown.
yLine = t1 ! -1000 1000 moveto makeFigure. 
t1 ! hide.

// create value fields
txtField1 = TextField ! create.
txtField2 = TextField ! create.

timer1 = Timer ! create.
timer1 ! 0.01 interval 600 duration.

timer1 ! [
  txtField1 ! ( Screen ! xPosition? ) set.
  txtField2 ! ( Screen ! yPosition? ) set.
  xLine ! -1000 (Screen ! yPosition?) moveto.
  yLine ! (Screen ! xPosition?) -1000 moveto.
] execute.

2012年8月28日火曜日

[Scala] Tuple

複数の値をまとめて取扱い時に便利な Tuple についてまとめておく。
特に要素が2つの Pair はさまざまな時に使うと思う。なんで Java に Pair がなかったのだろう。

このように、括弧で複数の値をくくると、Tuple オブジェクトが作成される。

val t1 = ("a" , 1);
println(t1.getClass().getName())

scala.Tuple2

値の型は何でもよい。値の数に応じて専用のクラスが用意されている。

2012年8月27日月曜日

[Scala] ””” (トリプルクォート)

文字列リテラルを記述する際に、""" (トリプルクォート)を使うことで、 「 \ 」のエスケープが不要になる。

println("aaa\nbbb");      // \n は改行コード扱い
println("aaa\\nbbb");     // \ をエスケープしたので「\n」という文字列
println("""aaa\nbbb""");  // \ は特殊文字扱いされない。

aaa bbb aaa\nbbb aaa\nbbb

2012年8月26日日曜日

[AppEngine] JDO でデータストアを使う

前回、PersistenceManagerFactory と データクラス が準備できたので、 作成・削除・更新操作・取得をやってみる。
各操作は、PersistenceManagerFactory から取得した PersistenceManagerに対して実行する。
  • 取得
    キー値で取得する際には、PersistenceManager#getObjectById が使える。
    それ以外に検索条件などで取得する際には、Query オブジェクトを使用する。
    Query query = pm.newQuery(MyData.class);
    @SuppressWarnings("unchecked") 
    List result = (List)query.execute();
    
  • 作成
    データオブジェクトを作成してプロパティをセットした後、 PersistenceManager#makePersistent を実行する。
    MyData data = new MyData();
    data.setName(req.getParameter("name"));
    pm.makePersistent(data);
    

2012年8月25日土曜日

[AppEngine] JDO でデータストアを使う(準備編)

アプリがデプロイして動くようになったので データストアを使ってみる。
App Engine のデータストアを使用するには、 JDO(Java Data Objects)、 JPA(Java Persistence API)、 および、App Engine 独自の Low Level API を使用する方法がある。

Google App Engine の スタートガイドでは JDO を使っている のでまずは JDO を使ってやってみる。

2012年8月24日金曜日

[AppEngine] AppEngine で Servlet+JSP を使う。

App Engine のプロジェクトで Servlet + JSP のパターンで動くか試してみる。 前回、プロジェクトを作成したときにはこんなフォルダ構成だった。

[Project-Folder]
  ...
  src/  META-INF/  jdoconfig.xml
                   persistence.xml

       [package]  XXXServlet.java

  war  favicon.ico
       idnex.html
       WEB-INF/   appengine-web.xml
                  logging.properties
                  web.xml
                  classes/   ...
                  lib/       ...

2012年8月22日水曜日

[ドリトル] プロパティや命令の探索

以前、self の記事でも調べたがもう少し調べておこう。 オブジェクトのメソッド(命令)の中でプロパティを参照する際には以下の順序で探索される。
  • 起点指定なし
    ローカル変数 → 自オブジェクトのプロパティ → プロトタイプのプロパティ → ・・・
    → ルートオブジェクトのプロパティ
  • self 起点
    自オブジェクトのプロパティ → プロトタイプのプロパティ → ・・・
    → ルートオブジェクトのプロパティ
  • 特定オブジェクト 起点
    指定オブジェクトのプロパティ → プロトタイプのプロパティ → ・・・→
    ルートオブジェクトのプロパティ

t1 = Turtle ! create.
t1:value = "T1".

t1:test = [ | ; value |
  value = "local".
  TextField ! (value) create.
  TextField ! (self:value) create. ].
t1 ! test.

local T1

「value」で指定した場合はローカル変数の値、「self!value」で指定した場合には t1 オブジェクトのプロパティ値が参照されている。

2012年8月21日火曜日

[AppEngine] デプロイしてみる

環境ができたので、まずはなんか作ってデプロイするところまでやってみよう。

作成するプロジェクトは、Google > Web Application Project。
とりあえずは Google Web Toolkit は使わない予定なので「Use Google Web Toolkit」は外しておく。

なんかできた。

[Project-Folder]
  .settings/  com.google.appengine.eclipse.core.prefs
              com.google.gdt.eclipse.core.prefs
              org.eclipse.jdt.core.prefs
              org.eclipse.wst.common.project.facet.core.xml

  src/  META-INF/  jdoconfig.xml
                   persistence.xml

       [package]  XXXServlet.java

  war  favicon.ico
       idnex.html
       WEB-INF/   appengine-web.xml
                  logging.properties
                  web.xml
                  classes/   ...
                  lib/       ...

2012年8月19日日曜日

[AppEngine] Google App Engine を使ってみる。

Google App Engine を使ってみよう。
まずは準備から。


サービスの利用開始


App Engineのホームページにアクセスする。
ここに SDK のダウンロードや、各種参考資料へのリンクがある。
この画面に「利用を開始する」というボタンがあるので押す。

2012年8月18日土曜日

[Scala] Eclipse Juno + Scala IDE

Eclipse を Indigo(3.4.2) から、Juno(4.2) に入れ替える。

Scala は Eclipse IDE 環境で使っていたのだが、 現時点での最新版 「Scala IDE for Eclipse 2.0.2 」が Juno をサポートしていないので、次期版の Helium の Nightly 版に差し替える。

Helium の Nightly 版は ここ
「Scala IDE Helium, Nightly, for Eclipse 4.2 (Juno)」 のプラグインを Eclipse からダウンロードする。Eclipse の Install New Software で指定する URL は http://download.scala-ide.org/nightly-update-juno-master-29x。
  • Scala IDE for Eclipse
  • Scala IDE for Eclipsedevelopment support
  • Scala IDE for Eclispe Source Feature
の3つが出てきた。「Source Feature」は「Scala IDE for Eclipse」のソースらしい(by Scala-IDE の Documentation )ので、とりあえずは、「Scala IDE for Eclipse」のみインストール。
(とりあえず最少セットでいく)。

ちなみに、この Scala-IDE はScala SDK 込なので別途 Scala SDK を入れる必要はない。
対応している Scala のバージョンは 2.9

動いた。Scala の ソースにもアクセスできる。とりあえずこれができれば十分。
OK。


2012年8月17日金曜日

Eclipse で Java のコードアシストが効かない。

Scala を使うようになってしばらくしてから気が付いたのだが、 Java のコードを書くときに、コードアシストが効かなくなっていた。

Eclipse の Preference で確認すると、 Java > Editor > Content Assist > Advanced で Java の proposals が外れていた。
Eclipse Junoを再設置したときに確認した初期設定は、
  • [X] API Tools Proposals
  • Java Non-Type Proposals
  • [X] Java Proposals
  • Java Type Proposals
  • [X] SWT Template Proposals
  • [X] Template Proposals
  • Word Proposals
なのだが、Java Proposals が外れていたので設定。 これで Java のコードアシストも効くようになった。

Eclipse Juno を新規設置して Workspaceを作成して、 Juno 用の Scala IDE (Helium) を設置してみたが、Java Proposals は外れなかった。
以前の Scala IDE のみで発生するのか、実は Eclipse Indigo の初期設定がこうなのか、もしくは全く別の要因だったのかは不明。



2012年8月16日木曜日

[ドリトル] サイクロイド曲線

サイクロイド (cycloid) とは、円がある規則にしたがって回転するときの円上の定点が描く軌跡として得られる平面曲線の総称である。

-- by ウィキペディア

ということなのだが、見方を変えると周回する点にX方向のオフセットを与えたものと見なすこともできる。
これならドリトルで簡単に描けそうなのでやってみよう。
forward による周回移動と水平移動の2段階移動になるため、移動後位置算出用の不可視タートルと描画用のタートルの2つ組を用意する。

2012年8月15日水曜日

[ドリトル] 放物線の反射

放物線を描いてみよう。y=x

VALUE_RANGE = 5.  // x = -5 to + 5
RESOLUTION = 100.
DRAW_SCALE = 200.
OFFSET_Y = -200.

t1 = Turtle ! create.
t1 ! 1 linewidth (blue) linecolor.
t1 ! penup.
[ | n ; x y |
  x = (n - RESOLUTION / 2) / RESOLUTION * VALUE_RANGE. 
  y = x * x.
  t1 ! (DRAW_SCALE * x) (DRAW_SCALE * y + OFFSET_Y) moveto.
  t1 ! pendown.
  t1 ! makeFigure.
] ! (RESOLUTION) repeat.

放物線に平行線を反射させると焦点に集まる。
ということでタートルを反射させてみる。

2012年8月14日火曜日

[ドリトル] 花火

季節がら、花火的なものを一つ作ってみる。
  • 重力を考慮する環境で1つタートルを打ち上げる。
  • 一定時間後、子タートルを放射状に展開し自身は消える。
  • 所定の世代数を消化するまで繰り返し。

2012年8月13日月曜日

[Scala] カリー化

前回、部分適用を見たので今回をカリー化。

カリー化とは、
複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。
--- by Wikipedia
だそうだ。Math.pow(Double, Double) : Double を例に使ってやってみよう。

  val powf : Double => (Double => Double) =
    (x : Double) => ( (y : Double) => Math.pow(x, y) );
  println(powf(2)(3))  

  val powfp : Double => (Double => Double) =
    (x : Double) => Math.pow(x, _);
  println(powfp(2)(3))  

前者は地道に、Double型の引数を一つとって「Double型の引数を一つとってDouble値を返す関数」を定義している。
後者は部分適用を使ってやってみた例。いずれも結果は同じ。


FunctionX トレイトのカリー化の実装


Function型の実装の記事で書いたように、Function2 ~ Function22 までの各トレイトには curried メソッドが定義されている。
Function2 での定義は以下のようになっている(アノテーション省略)。

trait Function2[-T1, -T2, +R] extends AnyRef {
  ...
  def curried: T1 => T2 => R = {
    (x1: T1) => (x2: T2) => apply(x1, x2)
  }
  ...

ちょっと見にくいのだが、T1型の引数を一つととって「T2型の引数を一つとってこの関数を apply() した結果を返す関数」を返す実装になっている。上の例の1つ目のものと同じパターン。
Function3 の実装を見てみよう。

trait Function3[-T1, -T2, -T3, +R] extends AnyRef {
...
  def curried: T1 => T2 => T3 => R = {
    (x1: T1) => (x2: T2) => (x3: T3) => apply(x1, x2, x3)
  }
...

T1型の引数を一つととって「T2型、T3型の引数をとって「T3この関数を apply() した結果を返す関数」を返す実装になっている。ただ、返る関数自体も Function4 以降も同じパターンで長くなっていくだけなので省略。


複数のパラメータリストをとる関数の定義


関数の定義時に複数のパラメータリストをとることができる。

    def powx(x : Double) : Double => Double = 
         (y : Double) => Math.pow(x,y);
    def powx2(x : Double)(y:Double) : Double = Math.pow(x,y);

上の powx はこれまで書いたように順当にカリー化してある関数。
一方、下の powx2 は複数のパラメータリストを受け取る形でカリー化している。
powx2 も「Double型引数を一つとって「Double型引数を一つとってDouble型を返す関数」を返す関数」となる。

  val f : Function1[Double, Double => Double] = powx2;

powx は関数を返す関数であるのに対して、powx2 のほうはあくまでも「複数のパラメータリストをとる」関数なので、関数自体の取り扱いが異なる。

    val f1 = powx(1.0);
    val f2 = powx2(1.0) _; 
//  val f3 = powx2(1.0);  // NG
    val f4 : Double=>Double = powx2(1.0);

上の例のように powx(1.0) は「Double => Double」を返すことが明らかなので f1 に代入できるが、 powx2(1.0) は「_」をつけて部分適用をすることによって代入ができる。「_」を省略するとエラーになる。(ただし、f4 のように変数の型を明記すれば、Scala の自動処理によって「_」が省略可能)



カリー化はなにがうれしいのか


結局カリー化するとどういういいことがあるのだろうか?
理論計算機科学の分野では、カリー化を利用すると、複数の引数をとる関数を、一つの引数のみを取る複数の関数のラムダ計算などの単純な理論的モデルと見なして研究できるようになる。 --- Wikipedia
これはどうでもいい。
カリー化をする現実の動機の1つに、カリー化することで後述する部分適用が行いやすくなることが挙げられる。たとえば、加算を行う関数 (+) をカリー化してから、最初の引数だけに 1 を適用すれば、インクリメント用の関数が簡単に作れる。 --- Wikipedia
こちらは Scala 本にも書いてある動機。Scala 本では、

  def multiplier(i: Int)(factor: Int) = i * factor;
  val byFive = multiplier(5) _

という例が記載されている。しかしこれにしても、

  def multiplier2(i: Int, factor: Int) = i * factor;
  val byFive2 = multiplier2(5, _:Int)

で十分ではないかという気もする。このあたりの感覚がよくわからない。

なお、上の例では変数の型を明示していないので「_:Int」と書いてあるところを単に「_」にするとエラーになる。このあたりは、前回の部分適用の記事を参照。



2012年8月12日日曜日

[Scala] 部分適用

部分適用。
部分適用された関数は、関数で定義された引数の一部がパラメータとして供給されない式です。
-- by プログラミング Scala
いわゆるオライリーの Scala 本によるとこういうことらしい。
関数を、「_(アンダースコア)」付きで呼び出してパラメータとして未決定のまま取り出す操作を部分適用と呼ぶ。「一部のパラメータのみを決定したもの」ではない。つまり、全部未定義でも部分適用に該当する。

  val fpow : (Double, Double) => Double = Math.pow _;
  println( fpow(2.0, 3.0));

8.0

ここの「 Math.pow _ 」が部分適用に相当する。
なお、 fpow(2.0, 3.0) は関数実行に見えるが、 apply の回で書いたように fpow.apply(2.0, 3.0) の省略形になっている。

部分適用というくらいなので、一部のパラメータを決定することもできる。

  val square : (Double) => Double = Math.pow(_, 2);
  println( square(3.0));      

9.0

引数を一つ確定したので、square は引数がひとつの関数になっている。たぶん部分適用という言葉から主にイメージする使い方はこの使い方だと思う。
上の例では変数の型を明示したがこれを省略した場合には、「_」に型指定が必要になる。

  val square1 = Math.pow(_:Double, 2);

型指定をしないと次のようなエラーになる。

  val square1NG = Math.pow(_, 2);       // --> NG!

missing parameter type for expanded function ((x$5) => Math.pow{<null>}(x$5{<null>}, 2{<null>}){<null>}) {<null>}

変数の型か「_」の型指定で明示的に省略されているパラメータの型を与える必要があるようだ。

ところで部分適用は匿名関数を定義するのとどう違うのだろうか。

  val fpow2 : (Double, Double) => Double 
      = (x : Double, y : Double) => Math.pow(x, y);
とか、
  val square2 : (Double) => Double 
      = (x : Double) => Math.pow(x, 2);

と書いたのとの違いが今一つ見えない。
書き方の違いだけ?わざわざ匿名関数を作らないでも「_」だけ書けばいいですよ、ということなのだろうか?


「_」の省略


基本的にメソッドや関数に「_」がついているものは部分適用が行われている。しかし、「_」は状況によっては省略することができる。
以下は、Scala 本の例。

  List("aaa", "bbb").map(println)
ここで TraversableLike トレイトの map の定義は、
  def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {

で、引数が一つの関数になっているので、map(println _) と書かずに map(println) と書くだけで部分適用が使用される。 別に、「_」一つくらいなら構わないと思うのだが。
同じ理由でこのようなコードもかける。

  val fpow : (Double, Double) => Double = Math.pow;

この記事の最初に出てきた例では実は「_」は省略できる。変数の型で引数を2つ取る関数であることを明示しているので、 Math.pow の後ろに「_」をつけなくても部分適用が行われる。
ここでは変数の型が明示されていることがポイントなので、変数の型を明示しないと「_」は省略できない。

  val fpowOK = Math.pow _;   // -->  OK
  val fpowNG = Math.pow;     // -->  NG


インスタンスメソッドへの部分適用


部分適用は、インスタンスメソッドに対しても適用できる。

  val secondToXofHello : Int => String = "HELLO".substring(1,_);
  println(secondToXofHello(4));

およそ実用性のある例とは思えないが、このようにして特定インスタンスのメソッドへ部分適用ができる。
こんなこともできる。

  val l = List(1,2,3,4).filter(2 <)
  println( l )

List(3, 4)

「 < 」はRichInt クラスの引数一つのメソッドなので「_」を省略して記述できる。
いろいろ省略しないで書くなら、「 ...filter(2.<(_)) 」 となる。
個人的には、「 ...filter(2 < _) 」ぐらいが一番わかりやすいかなと思う。



部分適用で一部のパラメータを決定することで関数の引数の数が減るため、関数のパラメータを減らす操作であるカリー化と混同しやすいそうだがこれらは全く別のものである。次回でカリー化操作を見てみよう。



2012年8月11日土曜日

[Blogger] 未来の投稿

Blogger で公開するときに、未来の日時を指定してから公開することができる。
今回はそのあたりの挙動を確認してみる。

Blogger で記事を作成して下書きの状態で「スケジュール」を選択し、「日付と時刻を設定」で未来の日時を設定してから「公開」を実行する。
するとこの記事はその時点では公開状態にならず、Blogger 管理ツールの投稿リストで「スケジュール済み」のリストに入る。公開状態ではないのでこの時点で Blogger で公開予定のアドレスにアクセスしても「このブログ内でお探しのページは存在しません。」になる。

あらかじめ指定しておいた日時になると公開状態になりアクセスできるようになる。
管理ツールでも「スケジュール済み」リストから「公開済み」のリストに移動する。


パーマリンク


各記事には記事固有のURLが割り当てられる。
この URL は、「http://xxxxx/2012/10/name-of-post」という形式で公開日の年と月が URL に付与されている。

スケジュールされた投稿の場合、公開ボタンを押した日ではなく実際に公開された年月を使用して URL が付与される。
これは過去の日時を指定して公開した場合も同様で、公開日として設定された日時で URL が付与される。

パーマリンクは一度公開されると公開を取り消して下書きにしないと変更されない。
公開済み記事の公開日時だけを変更しても URL は変わらない。いったん取り消して下書きにしてから再度公開すると、公開年月によって再度 URL が作成される。

スケジュール済みの記事の場合はまだ公開されていないので公開日時を更新すると URL は新しい公開年月のものになる。


スケジュール済みの記事の更新時の挙動


「スケジュール済み」になっている記事の編集画面の上部のボタン群は
「スケジュール」、「下書きに戻す」、「プレビュー」、「閉じる」になっている。

画面右側の「投稿の設定」のいずれかの項目を選択して完了ボタンを押下すると、
「公開」、「保存」、「プレビュー」、「閉じる」に代わる。
ここで「保存」を実行すると記事の公開スケジューリングが取り消されて「下書き」の状態に戻ってしまう。
記事の内容の更新の時にはボタンは「スケジュール」、「下書きに戻す」のままなのだが。

「スケジュール」と「公開」、「下書きに戻す」と「保存」という同じ位置にあるボタンの動きが同じなので、「投稿の設定」で完了した際に上部ボタン群のラベルが変わってしまうバグなのではないかと思う。


公開済みの記事の公開日を未来にする


すでに公開済みの記事の公開日時を未来の日付に変更して「更新」をする。
この場合は、この記事はスケジュールされた記事にはならず公開されたままになる。
この方法を使うと「未来に投稿された」記事を公開することができる。

2012年8月10日金曜日

[Blogger] nbsp

Blogger のテンプレートをカスタマイズしていて気が付いたのだが、 「&nbsp」(ノーブレークスペース)が使えない。 使うと、

テンプレートの形式が適切でないため、解析できませんでした。 すべての XML 要素が適切に閉じられているかどうかを確認してください。 <br/>XML エラー メッセージ: The entity "sbnp" was referenced, but not declared.
Error 500

というエラーになる。
空白を複数続けても表示時には1つ分にしかならないので、 スペースを空けたいときにはノーブレークスペースを使うのだが、これが使えないと、全角空白を使うしかなくなってしまう。
外人さんとか困らないのだろうか?


他は大丈夫だろうか?

さすがに、「 &lt ( < )」、「 &gt ( > )」 は大丈夫。
「&amp;(&:アンパーサンド)」、「&quot;(")」 もOK。
「&copy;(© コピーライト)」がNG。自分はあまり使わないけど、使う人は使うと思う。

「&copy;」 はエラーになったが、「&#169;」 や 「&#xA9;」 と書けば © が表示される。
同様に 「&nbsp;」 も「 &#160; 」「&#xA0;」と書けば期待通りに動作する。



出力される HTML ソースを見て気が付いたのだが、これらの文字参照はそのまま HTML に出力されるのではなく、 テンプレートエンジンが評価してしまっているようだ。「&#xA0;」とテンプレートに記載しておいても「 &#160; 」と10進表記で出力されている。

「 &lt; 」もエラーにはならなかったので気が付かなかったが、HTML 上はベタに「<」 になってしまっている。
なので、「HOGE&lt;BR&gt;HOHE」と記載すると「<BR>」になって改行されてしまう。
「<BR>」 と画面上に表示したかったら「&amp;lt;BR&amp;gt;」 としないといけない。

テンプレートをカスタマイズするときには気を付けよう。



蛇足だが、テンプレート上に Table 要素を作った際に、tdoby を使ったらエラーになった。TBODY と大文字にすればOK。
THEAD は thead でも問題ない。意味が分からない。
文字参照だけでなく、HTML 要素にも想定外の動きをするものがありそうだ。要注意。



2012年8月9日木曜日

[Blogger] 記事一覧

Blogger で不便なのは、アーカイブページやラベルページで記事の一覧がないこと。
もともと自分のメモ用に書いていたのだが、ある程度記事がたまると自分でも困る。
記事一覧みたいなガジェットを探していたのだが、 テンプレートカスタマイズで実現しているブログがあったので早速やってみることにする。

出所は、
"Holiday Webmaster Blog" では、以下のようなスクリプトになっている。

<b:if cond='data:blog.pageType != "item"'>
<b:if cond='data:blog.url != data:blog.homepageUrl'>
<ul id='post-title-navigation'>
<span>このページの記事一覧</span>
<b:loop values='data:posts' var='post'>
    <li>
    <b:if cond='data:post.title'>
      <data:post.dateHeader/> - <a expr:href='"#" + data:post.id'><data:post.title/></a>
    <b:else/>
      <data:post.dateHeader/> - <a expr:href='"#" + data:post.id'><data:post.id/></a>
    </b:if>
    </li>
</b:loop>
</ul>
</b:if>
</b:if>

これをテンプレートに追加するだけで、 アーカイブページやラベルページに記事一覧が表示される。
素晴らしい。

ほとんど目的達成してしまっているのだが、 「クリボウの Blogger Tips」によると同一日の2つ目以降のポストには 「data:post.dateHeader」が入ってこないとのこと。
確かに、Blogger のヘルプにもそう書いてある。

dateHeader がない行でレイアウトがずれてしまうため「クリボウの Blogger Tips」では日付を除去するという作戦をとっているが、 日付は表示したいので「なくても崩れない」方式で行くことにする。



というわけで、記事一覧は table 形式で出力する方式に変更。
また、元スクリプトだと静的ページでも記事一覧が出てしまうので、 「data:blog.pageType」が「static_page」なら表示しないようにして以下のコードを追加することにした。
挿入する箇所は、前回、 テンプレート中で現在表示されているページのタイプを判別した時と同様に

<b:widget id='Blog1' locked='true' title='ブログの投稿' type='Blog'>
の中の
<b:include data='top' name='status-message'/>
の直下。

<b:if cond='data:blog.pageType != "item"'>
<b:if cond='data:blog.pageType != "static_page"'>
<b:if cond='data:blog.url != data:blog.homepageUrl'>
<table id='post-title-navigation'>
<span>このページの記事一覧</span>
<b:loop values='data:posts' var='post'>
    <tr>
    <b:if cond='data:post.title'>
     <td>● <data:post.dateHeader/> - </td>
     <td> <a expr:href='"#" + data:post.id'><data:post.title/></a></td>
    <b:else/>
     <td>● <data:post.dateHeader/> - </td>
     <td> <a expr:href='"#" + data:post.id'><data:post.id/></a></td>
    </b:if>
    </tr>
</b:loop>
</table>
</b:if>
</b:if>
</b:if>

うん、いい感じになった。



2012年8月8日水曜日

[Blogger] テンプレート中で現在表示されているページのタイプを判別する。

Blogger のテンプレートカスタマイズではページのタイプ毎に表示したり非表示にしたりというコントロールをすることが多いので、現在表示しているページのタイプを取得する方法を確認しておく。

ページタイプの取得は、data:blog.pageType で取得できる。
Blogger のヘルプ によると取得できる値は以下の3つ。
  • item   --- 個別の記事
  • archive --- アーカイブページ
  • index   --- インデックスぺージ
の三種類。

早速やってみよう。


まずはテンプレートの編集。ウィジェットの中に書き込むので、 「レイアウト > HTML の編集」で開く「レイアウト > HTML の編集」画面で 「ウィジェットのテンプレートを展開」にチェックを入れる。
するとウィジェットの中身も展開されるので表示されているテンプレートもぐわっと長くなる。

今回は記事のタイプを、各記事が表示される部分の上に表示しようと思うので、
main セクションの Blog1 ウィジェットの中に記述する。具体的には、
<b:section class='main' id='main' showaddelement='no'>
というセクションの中の
<b:widget id='Blog1' locked='true' title='ブログの投稿' type='Blog'>
の中に記述することになる。

その長いウィジェットの中のどこが良いかということになるのだが、
<b:include data='top' name='status-message'/>
の直下あたりが良いらしい。

この status-message は、 モバイル用のメインの
<b:includable id='mobile-main' var='top'>
の中と、モバイル以外用のメインの
<b:includable id='main' var='top'>
の中にあるので必要な方(もしくは両方)に記述すればいい。
今回は、普通(非モバイル)で表示できればいいので 「id='main'」のほうに書く。



記述する内容。
今回は、if 文の使い方の練習も兼ねて、pegeType 値とそれに応じた文字を表示するようにする。

**** ページのタイプはこれだ ****<br/>
<data:blog.pageType/><br/>
<b:if cond='data:blog.pageType == "index"'>インデックス
<b:else />
  <b:if cond='data:blog.pageType == "archive"'>アーカイブ
  <b:else />
    <b:if cond='data:blog.pageType == "item"'>アイテム
    <b:else />不明なページタイプ
    </b:if>
  </b:if>
</b:if>
<br/><br/><br/>

プレビューでそれっぽくなっていることを確認して、「テンプレートを保存」。



さて、表示してみよう。
トップページ:
**** ページのタイプはこれだ ****
index
インデックス 
トップページはインデックスページなのか。

個別記事ページ:
**** ページのタイプはこれだ ****
item
アイテム 

アーカイブページ:
**** ページのタイプはこれだ ****
archive
アーカイブ 

ラベルページ:
**** ページのタイプはこれだ ****
index
インデックス 
ラベルの記事一覧ページは「インデックス」ページなのか。 トップページと同じタイプになっている。

静的ページ:
**** ページのタイプはこれだ ****
static_page
不明なページタイプ 
こんな値が返るなんてどこにもかいてなかったじゃん。

実験結果。 data:blog.pageType で取得できる値は以下の4つだった。
  • item    --- 個別の記事
  • archive   --- アーカイブページ
  • index    --- インデックスぺージ
  • static_page --- 静的ページのぺージ




[Blogger] Tableのスタイル

記事を書いててテーブルを使うことが時々あるので、 ある程度見栄えがするようにテーブルのスタイルを作った時のメモ。

ブロガー管理画面 > テンプレート > カスタマイズ > アドバンス > CSSを追加

追加した CSS はこんな感じ。

table.standard {
    border: 1px #000000 solid;
    border-collapse: collapse;
    border-spacing: 0;
}

.standard th {
    padding: 5px;
    border: #000000 solid;
    border-width: 0 0 1px 1px;
    background: #F5F5F5;
    font-weight: bold;
    line-height: 120%;
    text-align: center;
}

.standard td {
    padding: 5px;
    border: 1px #000000 solid;
    border-width: 0 0 1px 1px;
    text-align: center;
}

table タグ自体はレイアウト目的でも使っているので、クラスに standard をつけるようにした。
これでこのような table を書くと、

<table class=standard frame="box" rules="all">
<tr><th>Resource</th><th>Daily Quota</th></tr>
<tr><td>Datastore Entity Put Ops </td><td> 4,376</td></tr>
<tr><td>Datastore Entity Delete Ops </td><td> 4,254</td></tr>
<tr><td>Datastore Index Write Ops </td><td> 43,274</td></tr>
</table>

こんな感じのテーブルになる。

ResourceDaily Quota
Datastore Entity Put Ops 4,376
Datastore Entity Delete Ops 4,254
Datastore Index Write Ops 43,274

ちょっとヘッダの色が薄い気もするがok。



2012年8月7日火曜日

[Blogger] Bloggerのテンプレートに関する情報源について

テンプレートをいじる前にテンプレートの文法について確認しておこう。
知っておくべきは、テンプレートで使用できるカスタムタグと、テンプレート内で使えるデータについて。
ひととおり、Blogger のヘルプに記載されているので関連情報のありかをまとめておく。




2012年8月6日月曜日

IrfanView での日本語フォルダ問題

画像ビューワーとして IrfanView をずっと使っていたのだが、 このところ日本語フォルダ内にあるファイルの閲覧できない (表示はできるのだが、次のファイルへ進めない)状態になっていた。
別にメニューとかが英語なのは構わないのだがこれは困る。

K1Dunkさんのブログの情報 にて一発で解決。

  • IrFanView 起動
  • Options > Properties/Settings メニューで 「 Properties/Settings」ダイアログを開く。
  • Language を選択し、画面下にある
    「Load Unicode PlugIn as program start(....)」 のチェックをオフにする。

で解決。快適になった。深謝。



2012年8月5日日曜日

[Scala] tryBreakable

前々回前回と Scala の break が続いたのでもう一つ。

scala.util.control.Breaks の 実装を見てみると tryBreakable というメソッドがある。
これを使うと break でブロック式を脱出する際に break した際にだけ実行する文を記述することができる。

  def tryBreakableSample {
    import scala.util.control.Breaks;
    import Breaks.{ break, tryBreakable };

    tryBreakable {
      for (i: Int <- 1 to 5) {
        if (i == 3) break; 
        print(i);
      }
    } catchBreak {
      print("breaked")
    }
  }


12breaked

break 後に catchBreak の後のブロックが実行されている。
注意するべきは、try 文の finally 句と違って break しなかった際には実行されないこと。

...
        if (i == 100) break; 
...


12345


tryBreakable ... catchBreak の構造


例によって、省略記法で構造が分かりにくくなっているので省略せずに書いてみる。

  def tryBreakableSample2 {
    import scala.util.control.Breaks;

    Breaks.tryBreakable( {
      for (i: Int <- 1 to 5) {
        if (i == 3) Breaks.break; 
        print(i);
      }
    } ).catchBreak( print("breaked") );
  }  

ブロック式を受け取った tryBreakable が「何か」を返し、 その何かに対してブロック式を受け取る catchBreak メソッドを実行する構造になっていることがわかる。


tryBreakable ... catchBreak の実装


scala.util.control.Breaks の実装を見てみよう。

  trait TryBlock {
    def catchBreak(onBreak: => Unit): Unit
  }

  def tryBreakable(op: => Unit) = new TryBlock {
    def catchBreak(onBreak: => Unit) = try {
      op
    } catch {
      case ex: BreakControl =>
        if (ex ne breakException) throw ex
        onBreak
    }
  }

Breaks.tryBreakable が返しているのは TryBlock トレイトを実装したオブジェクト。 Breaks.tryBreakable が実行しているのはこのオブジェクトを作成して返しているだけ。

TryBlock トレイトはブロック式を受け取る catchBreak だけを持っている。
Breaks.tryBreakable が返す TryBlock トレイトオブジェクトでの catchBreak の実装は、
  • TryBlock オブジェクト生成時に受け取ったブロック式(= tryBreakable の引数)を実行し、
  • BreakControl がスローされたら、catchBreak の引数であるブロック式を実行する。
という作りになっている。

つまり、tryBreakable の引数として渡したブロック式が実行されるのは、 tryBreakable の中ではなく、TryBlock.catchBreak の中であることが分かった。



2012年8月4日土曜日

[Scala] Continue

前回、Scala での Breaks クラスを使った break の仕方を調べてみた。
break と同様に Scala には continue 文もないのだが、Breaks を使うとほぼ同じような書き方で continue 相当のことを実現できる。

まずは、普通に break。
  def breakSample10 {
    import scala.util.control.Breaks;
    val mybreaks = new Breaks;
    import mybreaks.{ break, breakable };

    breakable {
      for (i: Int <- 1 to 5) {
        if (i == 3) break; 
        print(i);
      }
    }
  }
--------------------------------
12

2012年8月3日金曜日

[Scala] break

Scala には break 文がない。
しかし break 用のクラスが用意されていて一応それっぽいコードを書くことができるようになっている。

まずは良く出てくる基本形。

  def breakSample1 {
    import scala.util.control.Breaks;
    val mybreaks = new Breaks;
    import mybreaks.{ break, breakable };

    breakable {
      println("before break");
      break;
      println("after break");
    }
    println("out of break");
  }


before break out of break

多少おまじないがあるが、一見、breakable 構文のようなものがあってそれで括っておけば break できるように見える。

import 文によるメソッド呼び出し先のオブジェクトやメソッド実行時の括弧の省略を一切無くしてみる。

  def breakSample2 {
    val mybreaks : scala.util.control.Breaks 
        = new scala.util.control.Breaks;

    mybreaks.breakable( {
      println("before break");
      mybreaks.break();
      println("after break");
    } );
    println("out of break");
  }

このように書くと、Breaks クラスの mybreaks オブジェクトに対して、 breakable メソッドを ブロック式を引数にして実行しているという構造が一目でわかる。


Breaks の実装


この break はどのように機能しているのだろう。
scala.util.control.Breaks の実装を確認してみる。
以下、scala.util.control.Breaks の実装の抜粋。

class Breaks {
  private val breakException = new BreakControl
  def breakable(op: => Unit) {
    try {
      op
    } catch {
      case ex: BreakControl =>
        if (ex ne breakException) throw ex
    }
  }
  ...
  def break() { throw breakException }
}
object Breaks extends Breaks
private class BreakControl extends ControlThrowable

break 文は専用の例外をスローしているだけ。
breakable 文では引数としてブロック式を受け取ってそれを実行し、 break 文でスローされた専用例外をキャッチしたら握りつぶして終了、という動作になっている。

一見 break っぽくなっているが、早い話が break の代わりに例外をスローして外側でキャッチするという構造になっている。


多重 break


先ほどの Breaks の実装を見ると、breakable でキャッチするのは 同一インスタンスの break でスローされた例外に限定されていることがわかる。
これを利用すると、多重脱出の break も書くことができる。

  def breakSample3 {
    val mybreaks1 = new scala.util.control.Breaks;
    val mybreaks2 = new scala.util.control.Breaks;

    mybreaks1.breakable({
      mybreaks2.breakable({
        println("before break");
        mybreaks1.break();
        println("after break");
      })
      println("out of break2");
    })
    println("out of break1")
  }


before break out of break1

「mybreaks1.break()」の後で、「"out of break2"」を飛ばして一気に「"out of break1"」に到達している。

このように多重で使う場合には、最初の省略型のようにインスタンスまで import してしまうとどちらにbreakable や break を実行しているのかわからなくなるので、Breaks クラスのインスタンスは省略できない。


breakable の無い break


breakable で括らずに break するとどうなるだろうか?

  def breakWithoutBreakable {
    val mybreaks = new scala.util.control.Breaks;
    mybreaks.break();
  }


Exception in thread "main" scala.util.control.BreakControl

スローされている例外を catch していないので当たり前といえば当たり前の結果。


コンパニオンオブジェクトの利用


Breaks にはコンパニオンオブジェクトが定義されているので、 この記事の最初に出てきた例はそのコンパニオンオブジェクトを使うともう少しシンプルになる。

  def breakSample0 {
    import scala.util.control.Breaks;
    import Breaks.{ break, breakable };

    breakable {
      println("before break");
      break;
      println("after break");
    }
    println("out of break");
  }

これならわざわざ Breaks オブジェクトを作る必要はない。
ただし コンパニオンオブジェクトはひとつなので多重 break をする場合には Breaks オブジェクトを自前で作る必要がある。

次回は、この break を使ってcontinue 相当のことを試してみる。



2012年8月2日木曜日

[Blogger] テンプレートのバックアップとリストア

Blogger をカスタマイズするには、いろいろなガジェットを使ったりHTML/JavaScript ガジェットを使ったりすることもできるが、多少凝ったことをするとなるとテンプレートに手を入れることになる。

テンプレートに手を出す前に必須なのがテンプレートのバックアップ/リストアなので、一度テスト用のブログを使ってやってみよう。



バックアップは、「テンプレート」画面で右上の「バックアップ/復元」ボタン。「テンプレート>バックアップ/復元」ダイアログで「テンプレートをすべてダウンロード」を実行。「すべて」と書いてあるが別に複数のテンプレートをまとめてダウンロードするわけではなくて現在使用しているテンプレートがダウンロードされる。
テンプレートは、template-3026474201568311803.xml というファイル名のXMLファイルとしてダウンロードされる。何回ダウンロードしてもファイル名は同じ。使用するテンプレートを変更するとサイズは変わるがファイル名はやはり同じ。ブログが違えばファイル名も変わるので、「template-」の後の数字は、ブログ毎の識別子か何かなのだろうか?

復元してみよう。まず検証用にダウンロードした時とは違うデザインを選んで適用しておく。
「バックアップ/復元」ボタン。「テンプレート>バックアップ/復元」ダイアログで「ファイルを選択」。ファイル選択ダイアログが表示されるが、ファイルの形式が「すべて」になっている。ダウンロードしたのがXMLファイルなのだからここでもファイルの形式はXMLにしておいてくれると楽なのに。ファイルを選択してアップロード。元のデザインに戻った。アップロードが完了した時点でブログに適用される。


元テンプレートとの関連付け


デザインはバックアップ時に戻るのだが、親テンプレートとの関連は切れてしまうようだ。

バックアップ時復元後

また、たとえばSimpleテンプレートを基にして作成→バックアップ→復元しても、画面上は動的ビューをカスタマイズしたようになってしまうので注意。



ガジェットについて


ガジェットの復元についても確認してみた。
位置情報などは元に戻るようだが、内容については部分的に復元される。

たとえば、「HTML/JavaScript」ガジェット。
配置位置を変更してもバックアップ時の場所に戻る。タイトルが変更されていても元に戻る。しかし、内容が変更されていても元には戻らない。 実際、テンプレートファイル中にも

<b:section-contents id='sidebar-right-1'>
<b:widget id='HTML2' locked='false' title='てすと' type='HTML'>
<b:includable id='main'>
  <!-- only display title if it's non-empty -->
  <b:if cond='data:title != ""'>
    <h2 class='title'><data:title/></h2>
  </b:if>
  <div class='widget-content'>
    <data:content/>
  </div>

  <b:include name='quickedit'/>
</b:includable>

となっていて、タイトル情報までは記録されているが内容までは記載されていない。
テンプレートをバックアップしてもガジェットの内容までは復元されないことには留意するべき。

このHTML/JavaScriptガジェットがレイアウトから削除した後で復元をしてみると、ガジェットも復元されるのだが、内容はやはり削除時の内容で復元された。
このあたりは動きから類推するしかないがガジェットは削除後もデータとしては Blogger に記録が残っていてその値が使われているのだろうか。



2012年8月1日水曜日

[Blogger] カテゴリ別記事一覧をつけてみた

ブロガーのラベルページでは、指定したラベルの付いた記事群が表示されるが一覧がないのであまり使い勝手がよくない。かといって手動で作るのもなんなので調べてみたらこんなのがあった。

他にもいくつか見つかったがだいたいソースはここのようだ。

2012年7月31日火曜日

[ドリトル] センサー

センサー付きのタートルを作ってみよう。
  • 自身から伸びるアンテナ(ヒゲ?)を持つ
  • アンテナは周期的に自身の周りを回転する。
  • 何かがアンテナに触れるとタートルはその時のアンテナの方を向く。
周りにエサを配置してアンテナがそれに触れたらそちらに向かう感じで。

2012年7月30日月曜日

[ドリトル] 平方数を求める

前回、円周率を算出してみたので今度は平方数を求めてみよう。
当たり前だが、sqrt 使用禁止。
√2、√3は簡単。
√2 は隣辺長1の直角2等辺三角形の底辺が √2 になる。

SCALE = 100.
t1 = Turtle ! create.
t1 ! 45 leftturn (SCALE) forward 90 rightturn (SCALE) forward.
Label ! ((t1 ! xPosition?) / (SCALE)) create.

2012年7月29日日曜日

[ドリトル] 円周率を求める

ふと思いついたのでやってよう。
タートルを使って円周率を求めてみる。
forward と rightturn で円を描けば周長がわかるので、「周長=直径×PI」より半円を描いた時の座標から円周率がわかる。

SCALE = 1.
APEX = 360.

t1 = Turtle!create hide.
[t1 ! (SCALE) forward (360.0/APEX) leftturn ] ! (APEX/2) repeat.

TextField ! (SCALE*APEX) create.
TextField ! (t1 ! yPosition?) create nextline.
TextField ! ((SCALE*APEX) / (t1 ! yPosition?)) create nextline.

「円周率=3.1416725」。おお、それなりの値が。

2012年7月28日土曜日

[Blogger] Blogger の画像ファイルの扱いについて

このブログで今まで主に使っている画像ファイルは「ドリトル」実行結果なので非常にシンプルなのが多い。なので、減色しても全く問題ないので、16 Color ( 4 bit ) PNG にしてサイズを小さくしている。
アップロードするファイルは数 KB ほどの物が多い。

Blogger では、画像を記事に埋め込むと元のファイルとは別にインライン表示用の画像が生成される。
ところが、3 KB ほどのサイズの元画像がインライン表示用には 10 KB 程になってしまったりと元画像よりサイズが大きくなってしまうことがよく発生する。いったいどういうことなの?

というわけでBloggerでの画像ファイルの扱いについて調べてみた。

2012年7月27日金曜日

[Scala] Function 型の実装

前回、関数の型について調べたので、今回はその実装について見てみることにする。

Function系のトレイトは、引数が1つの Function1 トレイトと引数が2つ以上からなる Function2 ~ Function22 までのトレイトでは実装している関数が異なる。 共通しているのは関数を実行する apply と文字列化用の toString。

  def apply(v1: T1): R
  override def toString() = "<function1>"

上は Function1 トレイトの例。他も同様。apply は抽象メソッドで toString は実装付き。

Function1 ではこの他に関数合成に関する compose と andThen が実装付きで定義されている。
一方、Function2 ~ Function22 では、curried と tupled がそれぞれ実装付きで定義されている。 (curry は deprecated されて curried になっている)。

まずは、Function1 から見ていこう。


Function1 トレイトの compose と andThen はこのようになっている。

  /** Composes two instances of Function1 in a new Function1, with this function applied last.
   *
   *  @tparam   A   the type to which function `g` can be applied
   *  @param    g   a function A => T1
   *  @return       a new function `f` such that `f(x) == apply(g(x))`
   */
  def compose[A](g: A => T1): A => R = { x => apply(g(x)) }

  /** Composes two instances of Function1 in a new Function1, with this function applied first.
   *
   *  @tparam   A   the result type of function `g`
   *  @param    g   a function R => A
   *  @return       a new function `f` such that `f(x) == g(apply(x))`
   */
  def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }

compose は関数の合成を行うメソッド。自関数 f( T1 ) に対して、g( A )=>T1 (要は戻り値の型が自関数の引数と同じ関数)を受け取って、f( g( A ) ) の結果になる関数を作成する。

andThen も関数の合成を行うが適用順序が逆になる。引数が自関数の戻り値と同じ型になる関数gを受け取り、 g(f(A)) の結果になる関数を作成する。

やってみよう。

    val f : Int => Int = (x : Int) => x * 3;
    val g : Int => Int = (x : Int) => x % 3;
    
    // f(g(x)) -> (x % 3) * 3   g を実行した結果にfを実行
    val fg : Int => Int = f.compose(g);
    println("fg= " + fg(5));    
    
    // g(f(x)) -> (x * 3) % 3   fを実行してからgを実行。
    val gf : Int => Int = f.andThen(g);
    println("gf= " + gf(5));


fg= 6 gf= 0

予想通りの結果になった。



次はFunction2~Function22 トレイト で定義されている curried と tupled を見てみよう。

  /** Creates a curried version of this function.
   *
   *  @return   a function `f` such that `f(x1)(x2) == apply(x1, x2)`
   */
  def curried: T1 => T2 => R = {
    (x1: T1) => (x2: T2) => apply(x1, x2)
  }

  /** Creates a tupled version of this function: instead of 2 arguments,
   *  it accepts a single [[scala.Tuple2]] argument.
   *
   *  @return   a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)`
   */
  def tupled: Tuple2[T1, T2] => R = {
    case Tuple2(x1, x2) => apply(x1, x2)
  }

curried はカリー化された関数を返す。
カリー化 (currying) とは、計算機科学分野の技法の一つ。複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること(by Wikipedia)。
要は 1つの引数を受け取って、残りの引数を受け取って結果を返すような関数を返す操作のことらしい。 このあたりはいずれ別途調べてみることにする。

tuppled は引数をタプルにした関数を返す。引数が1つになるのでFunction1 型になる。

とりあえず使ってみる。

    val addFunc : (Int, Int) => Int = (x: Int, y: Int) => x + y;

    val curriedAdd : Int => (Int => Int) = addFunc.curried;
    println( curriedAdd(2)(3));
    
    val tupledAdd : Tuple2[Int, Int] => Int = addFunc.tupled;
    println( tupledAdd( (2,3) ));


5 5

こんな感じ。
「 val curriedAdd : Int => (Int => Int) 」は、普通は「val curriedAdd : Int => Int => Int 」と書けばいいのだが、何が起きているの理解しにくいのであえて括弧付きで書いてある。

タプル化したバージョンも「 tupledAdd( 2,3 ) 」と普通に 2 引数で書けば暗黙的にタプルが生成されて実行できるのだが何をしたのかわからなくなるので明示的にタプルを作って渡している。
このようにタプル化して 1 引数化することで、Function1 にしかない関数合成関数を使えるようになる。



2012年7月26日木曜日

[ドリトル] リサージュ図形を描く(三角関数禁止)

ドリトルのサンプルにリサージュ図形 を描くものがある。
これはこれで楽しいのだが、三角関数は子供に説明できないので三角関数を使わずに書いてみることにしよう。
forward 命令と leftturn 命令でタートルに円運動をさせてそこから X 座標と Y 座標を取得するようにする。

2012年7月25日水曜日

[Scala] 関数の型

たとえば、Int型 の引数をとってその倍を返す関数はこのような感じになる。

  val f : (Int) => Int =  (x : Int) => x*2;
  println(f(10))

つまり、「 (Int) => Int 」が変数 f の型になる。
関数を実行するときには、f(10) になるのだが、例によってapply が省略されているので、 省略せずに書くと、f.apply(10) になる。もちろん結果は同じ。

関数に型があるということは関数もオブジェクトなわけで、実際、引数の数に応じて Function1 ~ Function22 というクラスが用意されている。つまり、

    val f2 : Function1[Int,Int] =  (x : Int) => x*2;
    println(f2(10))

というように書くこともできる。むしろこちらが正式な書き方で「(Int) => Int」のほうがシンタックスシュガーにあたる。
「 Function1[Int,Int] 」は引数が1つで Int型、戻り値も int であることを表している。 Int型の引数を2つとって戻り値がDoubleの場合はこうなる。

var f: (Int, Int) => Double = (x: Int, y: Int) => (x + y) / 2.0;
var f2: Function2[Int,Int,Double] = (x: Int, y: Int) => (x + y) / 2.0;

Function22まではあるが、Function23 はない。そうなると引数を23個にしてみなくなるのが人間というものだろう。

    val f23 : (
        Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
        Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
        Int, Int, Int
        ) => Int = null;

type Function23 is not a member of package scala

Function23 が見つからないそうだ。 普通に引数が23個のメソッドも定義できないのだろうか?

  def f23(
         x1:Int,  x2:Int,  x3:Int,  x4:Int, x5:Int, 
         x6:Int,  x7:Int,  x8:Int,  x9:Int, x10:Int,
        x11:Int, x12:Int, x13:Int, x14:Int, x15:Int, 
        x16:Int, x17:Int, x18:Int, x19:Int, x20:Int,
        x21:Int, x22:Int, x23:Int
      ) : Int = 0;

定義できた。どうなってるのだろう。

    val f = f23 _;

missing arguments for method f23 in object FuncTest; follow this method with `_' if you want to treat it as a partially applied function

メソッドとして定義することはできるが、それをオブジェクトとして取り扱うことができないということのようだ。引数が 22 個までなら上のコードで問題ない。

ちなみにメソッドとして定義されているものを関数オブジェクトとして取り扱うときにはこのようにメソッド名の後ろに「 _ 」をつける。部分適用を使って関数として取り出しているような感じ



Function の実装を確認してみよう。

@annotation.implicitNotFound(msg = "No implicit view available from ${T1} => ${R}.")
trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R] extends AnyRef

見にくいのでアノテーションを取っ払うと、

trait Function1[-T1, +R] extends AnyRef

関数の引数に対応する型パラメータが反変、戻り値に対応する型パラメータは共変になっている。 他の FunctionXX も引数に相当する型パラメータが増えているだけで基本は同じ。

ところで、Function1 では引数は @specialized アノテーションで、Int、Long、Float、Double を特別扱いしているのに対して、Function2 で特別扱いしているのは、Int、Long、Double でFloatが抜けている。
戻り値は Unit、Boolean、Int、Long、Float、Double で同じ。
一方、Function3 以降では引数、戻り値ともに特別扱いなし。

@specialized アノテーション はコンパイルするとクラス数が増えるのでよく使うと思われるものに限定しているのだろう。

次回は、Function系クラスの実装を確認してみよう。



2012年7月24日火曜日

[ドリトル] キーボード操作でドリフト亀

ドリトルでキーボードイベントを拾ってみた。

button1 = Button ! "button" "UP" create.
button1:action = [self! "hoge" set].

GUIオブジェクトを作成する際に第 2 引数でキーと関連付けておけば、 キー押下時に当該オブジェクトの action 命令が呼び出される。うーん、シンプル。

label1 = Label ! "label" create.
button1 = Button ! "button" "UP" create hide.
button1:action = [label1! "hoge" set].

こんな感じにイベントを受け取るオブジェクトが hide されていてもちゃんと action は発生する。

2012年7月23日月曜日

サイトマップの登録

Google の ウェブマスターツール で「サイトマップの登録」という機能がある。
使い方が良く解らなかったのだが、 Googleにサイトマップを登録する(Bloggerブログ版) にわかりやすい解説があったのでやってみた。

2012年7月22日日曜日

[ドリトル] self

self(自分)の使い方を確認しておこう。

lblResult = Label ! "result" create.
lblResult2 = Label ! "result2" create nextline.

t1 = Turtle ! create.
t1Child = t1 ! create.
t1:value = 1.

t1Child:test1 = [ lblResult ! (value) set ].
t1Child:test2 = [ lblResult2 ! (self:value) set ].

t1Child!test1.
t1Child!test2.

結果はいずれも 「1」になる。self 指定も無指定も検索起点は 自オブジェクトで、自オブジェクトにプロパティ値が設定されていないので親のプロパティ値が取得される。
ちなみに、「 :value 」を指定すると起点がルートになるので、「 undef 」になる。

2012年7月21日土曜日

[Scala] 変位指定と isInstanceOf

前回の 変位指定 の続き。
変位指定付きの型のオブジェクトを isInstanceOf[ T ] で検査した場合の挙動を確認しておこう。

まずは共変から。

object VarianceSample {
  def main(args : Array[String]) {
    var covariantStr : Covariantable[String] = new Covariantable[String];
    var covariantAny : Covariantable[AnyRef] = new Covariantable[AnyRef];

    println(
       "Covariantable[String] is instance of Covariantable[AnyRef]: " 
        + covariantStr.isInstanceOf[Covariantable[AnyRef]]);

    println(
        "Covariantable[AnyRef] is instance of Covariantable[String]: " 
        + covariantAny.isInstanceOf[Covariantable[String]]);
  }
}

class Covariantable[+R] {
  def hoge(): R = null.asInstanceOf[R];
}


Covariantable[String] is instance of Covariantable[AnyRef]: true Covariantable[AnyRef] is instance of Covariantable[String]: true

あれ?
共変なので、[String] is instance of [AnyRef] は true でも反対は false と思ったのだが、 両方とも true になった。

2012年7月20日金曜日

[ドリトル] 図形の回転

少し思うところがあったので、図形を回転させる際の中心について確認しておこう。
まずはシンプルに ( 0, 0 ) に円を描いて回転させる。

t1 = Turtle ! create.
t1 ! 50 circle.
shape1 = t1 ! makefigure.

// mark initial position
shapeOrg = shape1 ! create (blue) paint.  

// rotate shape.
[ shape1 ! create.
  shape1 ! 60 rightturn.
] ! 6 repeat.
t1 ! penup movetocenter.

2012年7月19日木曜日

[Scala] 変位指定: 共変、反変、非変

Scala のコードを見ているとよくこんなコードに当たる。

trait Traversable[+A] extends TraversableLike[A, Traversable[A]] ...

この +A ってなんだろう。ジェネリクスの指定関係だということはわかるのだが。
調べてみたら、共変、反変、非変というジェネリクスの性質を指定するもののようだ。

2012年7月18日水曜日

[ドリトル] QIX

跳ね返り命令を使ってみよう。
昔あったQIXという陣取りゲームに出てくるあの南京玉すだれみたいなやつを書いてみることにする。
例によって基本方針。

  • 2匹のタートルをエリアの壁に反射させながら動かす。
  • 3匹目が両タートルの間に線を描画する。
  • 一本ごとに図形化し配列に格納する。古くなった線は消していく。

こんな感じでそれっぽくなるだろうか。

2012年7月17日火曜日

[ドリトル] 跳ね返り (四角形)

前の記事で 「反射する方向は、入射角と最初に引いた線の角度で決まって、その線上のどちら側に反射するかだけが実際に反射する面との相互作用で決まる」と書いた。
ところで、反射後の角度は、反射面の角度の2倍で効くので90度の場合は180度方向が変わるわけで、反射方向はドリトルが補正するから正しい角度に反射しそうな気がする。
そうなら、polygon命令で描いた矩形でも(forward×4も)正しく反射するはず。

t1 = Turtle ! create.

t1 ! penup -100 100 moveto pendown.
t1 ! 100 4 polygon.
shape1 = t1 ! makefigure.
t1:collision = t1:bounce. 

t1:go = [ | length | 
  [ ! 1 forward ] ! (length) repeat ].

t1 ! (red) linecolor.
t1 ! penup 0 200 moveto -120 direction pendown 300 go.
t1 ! penup 100 200 moveto -120 direction pendown 300 go.
t1 ! penup -100 -100 moveto 60 direction pendown 300 go.
t1 ! penup -200 -100 moveto 60 direction pendown 300 go.

4方向から当ててみたがやはり四角形はうまく反射するようだ。
内側から当ててみよう。

2012年7月16日月曜日

[ドリトル] 跳ね返り (円)

前の記事で跳ね返りをやったので、もう少し続けてみる。 今度は円。

t1 = Turtle ! create.

// ターゲット作成
t1 ! penup -100 100 moveto pendown.
t1 ! 100 circle.
t1 ! penup 0 direction movetocenter.
shape1 = t1 ! makefigure.
t1:collision = t1:bounce. 

// 一歩づつ進める。
t1:go = [ | length | 
  [ ! 1 forward ] ! (length) repeat.
].

// 初期位置を下にずらしながらターゲットに当てる。
// (100, -100) - ( 100, 100)
t1 ! 1 linewidth (red) linecolor.
[ | count | 
  y = 100 - (count * 10).
  t1 ! penup 150 (y) moveto 180 direction pendown.
  t1 ! 600 go.
] ! 20 repeat.

あれ、全部まっすぐ跳ね返ってきた。
円を少し回転させてみる。ついでにタートルのサイズも少し小さくしてみよう。

2012年7月15日日曜日

[ドリトル] 跳ね返り

Turtle には bounce (跳ね返る)命令があり、跳ね返り動作を簡単に記述することができる。 面白そうなので早速使ってみよう。

t1 = Turtle ! create.

// ターゲット作成
t1 ! penup -200 100 moveto pendown 45 rightturn.
t1 ! (100 * sqrt(2)) forward 90 rightturn (100 * sqrt(2)) forward.
t1 ! penup 0 direction movetocenter.
shape1 = t1 ! makefigure.

// Collision 動作を bounce動作に置き換える。
t1:collision = t1:bounce. 

// 一歩づつ進める。
t1:go = [ | length | 
  [ ! 1 forward ] ! (length) repeat.
].

// 初期位置を下にずらしながらターゲットに当てる。
t1 ! 1 linewidth (red) linecolor.
[ | count | 
  y = 100 - (count * 10).
  t1 ! penup 100 (y) moveto 180 direction pendown.
  t1 ! 600 go.
] ! 20 repeat.

[Scala] apply

val a1 : Array[Int] = new Array(5);
val a2 : Array[Int] = Array(5);

誰だってこのコードを見たら、「 Scala って new は省略できるんだ。」って思う(と思う)。

val a1 : Array[Int] = new Array(5);
val a2 : Array[Int] = Array(5);
println("a1 size = " + a1.length);
println("a2 size = " + a2.length);


a1 size = 5 a2 size = 1

で、「あれっ」となる。

val a1 : Array[Int] = new Array(5);
val a2 : Array[Int] = Array(5);
println("a1.toSeq = " + a1.toSeq);
println("a2.toSeq = " + a2.toSeq);


a1.toSeq = WrappedArray(0, 0, 0, 0, 0) a2.toSeq = WrappedArray(5)

できた Array の中身はこんな感じになっている。
(ArrayそのもののtoStringは「a1 = [I@7f188439」のようになってしまう。)

「 Array(5)」で省略されていたのは、apply という名のクラスメソッド。
省略せずに書くと、「Array.apply(5)」になる。


クラスに対する Apply


クラス名に「(」が続いた場合には、apply メソッドが呼び出される。
通常はオブジェクトの生成(ファクトリ)として使用されるがコンストラクタと違って、 そのクラスのオブジェクトを返す必要はない。実際、List.apply も

val l : List[Int] = List(1,2,3); 
println("List.apply  = " + l.getClass());


List.apply = class scala.collection.immutable.$colon$colon

と謎なクラスを返している。「val l : List[Int]」に代入できていることから List の派生クラスになるわけなのだが、実際には派生クラスを返す必要さえない。
なのでこういうこともできてしまう。

object ApplySample {
  def main(args : Array[String]) {
    val s : String = ApplySample(10);
    println(s)
  }
  def apply(a: Int) : String = "hello." + a;
}

hello.10

引数をとるようにしたが引数がない場合でも同様なことができる。
apply メソッドはそのクラスまたはその派生クラスのオブジェクトを返すのが慣例になっているそうなので、 あまり変なことはしないほうがいいとは思う。


オブジェクトに対するApply


オブジェクトに対しても同様で、オブジェクトに括弧を続けるとオブジェクトに定義されている apply が呼ばれる。

val a : Array[Int] = Array(100,200,300);
println(a(1));

200

これで配列の添字アクセスのようなことができるようになっている。

関数オブジェクトに対する呼び出しも apply が省略されている。

val f: (Int) => Int = (x: Int) => x * 2;
println(f(10))
println(f.apply(10))

既存の関数をオブジェクト化した場合も同じ。

println(Math.sin(Math.Pi / 2));
println((Math.sin _).apply((Math.Pi / 2)));

ただし、直接に関数を実行したときには、apply が省略されているわけではないので、 「 Math.sin.apply( Math.Pi ) 」と書くことはできない。



いずれにしても、apply は Scala の文法的には特別扱いになっているが、メソッドそのものが特別なわけではない。


2012年7月14日土曜日

[Scale] 数値指定のfor文について

for (i : Int <- 1 to 5) { ... }

以前、for文の記事 を書いたとき、なぜ、わざわざ java の for ( int i=0; i<10; i++) と異なる構文を用意したかと思っていたが、 実はこういうことだった。

val range : Range = 1 to 5.
for (i : Int <- range ) { ... }

Range 型オブジェクトに対する 拡張 for 文だった。
(「拡張」 for 文というか、結局 Scala の for 文はこの形式だけ)

Scala では「1」や「2」などの primitive もオブジェクト扱いなのでメソッドが呼び出せる。
値を返すメソッドは中置記法で書けるので一見気が付きにくい。

for (i : int <- 1 to 5) { ... }   も

for (i : int <- 1.to(5)) { ... }

と書けば Int 型のメソッドが実行されて何かができていることが一目でわかる。
どうも Scala の中にはこういう罠があちこちにあるような気がする・・・



Intクラスのドキュメンテーションによれば、

 *  There is an implicit conversion from [[scala.Int]] => [[scala.runtime.RichInt]]
 *  which provides useful non-primitive operations.

とうことなので実際に to 等のメソッドが用意されているのは RichInt クラスになる。
RichInt クラスで定義されている Range 型を返すメソッドを見てみると、

  def until(end: Int): Range = Range(self, end)
  def until(end: Int, step: Int): Range = Range(self, end, step)
  def to(end: Int): Range.Inclusive = Range.inclusive(self, end)
  def to(end: Int, step: Int): Range.Inclusive = Range.inclusive(self, end, step)

がある。
ステップ指定付きの to() を使ってみよう。

for (i : Int <- 1 to (10,2)) print(i);

13579

until() が Range 型を返しているのに対して、 to() は Range.Inclusive を返している。
Range 型では終端値は含まないのに対して、その派生型である Range.Inclusive は終端値を含むという違いがある。

for (i : Int <- 1 to 5) print(i);
println;
for (i : Int <- 1 until 5) print(i);

12345 1234



[ドリトル] 回転するカメ その2


前回の続き。 自転しながら動くタートルを作る。

前回は独自の「進行方向」プロパティを用意して、forward する際に、角度と移動距離から三角関数で移動後の位置を求めた。
いまいちタートルグラフィックスぽくないので別のやり方でやってみる。三角関数禁止。

基本戦略。
  • 進行方向を向くタートル(非可視)と回転するタートルの2匹組にする。
  • 片方のタートルが外から使える外部タートルでもう一匹は内部タートル
いくつかのオプションがあるので比較検討する。
多きくわけて、「外部/内部どちらが回転するか」、「外部/内部どちらが描画するか」の組み合わせて設計が分かれそう。

2012年7月12日木曜日

[ドリトル] 回転するカメ


前回の記事で タイマーが使えるようになったので使ってみる。
自転しならが円を書く Turtle を作ってみよう。

プロトタイプとしてして作って、使うときにはなるべく自然に Turtle として使えるようにする。

基本戦略。
  • 自身で回転専用の Timer を保持し、一定の速度で自身を回転させる。
  • 実際に進む向きは、専用のプロパティとして保持する。
  • forward をオーバーライドして、実際に進む向きから自身の移動位置を算出する。
  • right/leftturn をオーバーライドして、実際に進む向きのプロパティ値の更新をする。
こんな感じ。create 時に回転速度を引数として与えるようにしてある。

2012年7月11日水曜日

[ドリトル] Timerを使う

タイマーを使ってみよう。
タイマーで定期的な実行ができる。動きが見えるようにゆっくり動かす時に使う。
aTimer ! [ブロック] execute. であらかじめ指定したインターバルで指定回数(または指定時間)実行を繰り返すことができる。

周回する Turtle の速さを Slider で変えてみよう。
Slider を動かすとそれで周回する Turtle の速さを変える。

t1 = Turtle ! create penup 150 back pendown.
slider1 = Slider ! create.
label1 = Label ! (slider1!value?) create.
timer1 = Timer ! create.

slider1:action = [ 
  label1 ! ( self ! value?) set. 
  timer1 ! (0.1 * ( self ! value?) / 50) interval.
].

timer1 ! 0.1 interval 360 times.
timer1 ! [
  t1 ! 10 leftturn 15 forward.] execute.

2012年7月10日火曜日

[ドリトル] 衝突判定 集中砲火版


前回の続きで、衝突判定でもう少し遊んでみよう。
今度は、360度全周囲から突入してみる。
基本方針は以下の通り。
  • 中心にターゲットを配置する。
  • 一度ずつ角度を変えて中心から一定距離進み、pendown して衝突するまで戻る。

t1 = Turtle ! create.

// create target.
TARGETSIZE = 100.
HALFSIZE = targetSize / 2.
t1 ! penup (HALFSIZE) back pendown 1 linewidth.
t1 ! 90 leftturn (HALFSIZE) forward 90 rightturn (TARGETSIZE) forward.
t1 ! 90 rightturn (TARGETSIZE) forward 90 rightturn (TARGETSIZE) forward.
t1 ! 90 rightturn (HALFSIZE) forward 90 leftturn.
t1 ! makefigure (blue) paint.
t1 ! penup movetocenter.
collisioned = false.

t1:backUntilCollision = [ |; count | 
   collisioned = false.
   count = 0.
   [ (collisioned ! not) ! (count < 200) allTrue ] ! while [
     self ! 1 back.
     count = count + 1.
   ] execute.
   self ! penup movetocenter. 
].

t1:collision = [ collisioned = true. ].

// try to collision
inCollision = false.
[ | y |
  t1 ! penup movetocenter.
  t1 ! 1 rightturn 200 forward.
  t1 ! pendown.
  t1 ! backUntilCollision.   
] ! 360 repeat.  
おお。いい感じで衝突判定されている。

2012年7月9日月曜日

[ドリトル] 衝突判定

Dolittleでは、Turtle と 図形との間で衝突判定ができる。
Turtleが他の図形と重なったと判定された時に、 collision命令(「衝突」命令)が実行される。

面白そうなので早速使ってみる。
どのくらいの範囲で衝突したとみなされるのか調べてみよう。

基本的な考え方は以下の通り。
  • ターゲットとなる図形を書く。ターゲットは20x20の正方形
  • Y座標を上から下へずらしながら、左から右へTurtleを動かし衝突するか調べる。
  • 最初に衝突したY座標と最後に衝突したY座標を表示する。
やってみよう。

2012年7月8日日曜日

[ドリトル] GUIイベントの同時実行性

ボタンを押してアクションが実行されるのだが、実行中も少なくとも見た目上はGUI操作などはブロックされておらずバックグランド的に動いているように見える。

確認してみよう。

t1 = Turtle ! create.
t2 = t1 ! create.
t2 ! penup 200 forward.
btn1 = Button ! "No.1" create.
btn2 = Button ! "No.2" create.
btn1:action = [ t1 ! (l1) xcircle].
btn2:action = [ t2 ! (l2) xcircle].

l1 = Label ! "***********" create.
l2 = Label ! "***********" create.

t1:xcircle = [ | myLabel |
  myLabel ! "draing..." set.
  [
    self ! 1 forward 1 rightturn.
  ] ! 360000 repeat.
  myLabel ! "done" set.
].

[ドリトル] GUIをつける

GUI部品も用意されているようなので使ってみよう。
ボタン(Button)、ラベル(Label)、フィールド(TextField)、選択メニュー(SelectMenu)、スライダー(Slider)が用意されている。

t1 = Turtle!create.
Label ! "Depth" create.
field1 = TextField ! 1 create 50 45 size.
btnRun = Button ! "Run" create 80 45 size.
btnClear = Button ! "Clear" create.
lblStatus = Label ! "" create.

t1:koch = [
  | level width ; newWidth |
  [level <= 0 ] ! then [
     self ! (width) forward.
    ] else [
     newWidth = width / 3.
     self ! (level - 1) (newWidth) koch.
     self ! 60 leftturn (level - 1) (newWidth) koch.
     self ! 120 rightturn (level - 1) (newWidth) koch.
     self ! 60 leftturn (level - 1) (width - 2 * newWidth) koch.
   ] execute. 
].
btnRun : action = [ 
  lblStatus ! "drawing..." set.
  t1 ! penup movetocenter 250 back 90 rightturn 100 forward 90 leftturn pendown.
  t1 ! (field1!get) 500 koch.
  lblStatus ! "done." set.
].
btnClear : action = [
  | ; shape1 |
  lblStatus ! "clearing..." set.
  shape1 = t1 ! makeFigure.
  shape1 ! hide.
  lblStatus ! "done." set.
].

[Scala] 実装付き trait の仕組み

前の記事で書いたように、Scala の trait には、
  • 実装を持つことができる。
  • クラスは(Java の Interface と同様に) 複数の trait を実装することができる。
という特徴があるので、多重継承みたいなことができてしまう。
(ちなみに、trait を実装することを Scala では ミックスイン というらしい。)

Scala は Java の上で動くわけなので Java でできないことはできないわけなのだが、どのように実現されているのだろうか?
例外を発生させてスタックトレースを見てみることにする。

まずは、普通にクラスを extends した場合。

object TraitSample {
    def main(args : Array[String]) {
        new English().hello();
    }
}

class Greetable {
  def hello() : String = {
    throw new IllegalArgumentException("in Greetable");
  }
}

class English() extends Greetable {
}

Exception in thread "main" java.lang.IllegalArgumentException: in Greetable at Greetable.hello(TraitSample.scala:9) at TraitSample$.main(TraitSample.scala:3) at TraitSample.main(TraitSample.scala)

普通に見慣れた感じのスタックトレース。スタック中に English.hello()は出現していない。

次に、trait を使ってみる。

object TraitSample {
    def main(args : Array[String]) {
        new English().hello();
    }
}

trait Greetable {
  def hello() : String = {
    throw new IllegalArgumentException("in Greetable");
  }
}

class English() extends AnyRef with Greetable {
}

Exception in thread "main" java.lang.IllegalArgumentException: in Greetable at Greetable$class.hello(TraitSample.scala:9) at English.hello(TraitSample.scala:13) at TraitSample$.main(TraitSample.scala:3) at TraitSample.main(TraitSample.scala)

ふむ。
このスタックトレースを見ると、まず実装クラスの English.hello() が実行されて、そこから、Greetable$class.helloというクラスが呼び出されていることがわかる。

つまり、実装クラスにメソッドが生成されるとともに 実装 trait のオブジェクトも生成されていて、 実装クラスのメソッドから実装 trait オブジェクトのメソッドが実行される、という構造になっているようだ。

[Scala] trait

Scala では Java でいうところの Interface は trait という。
trait を少し使ってみる。

object TraitSample {
    def main(args : Array[String]) {
        val eng : English  = new English();
        println(eng.hello());
    }
}

trait Greetable {
  def hello() : String;
}

class English() extends AnyRef with Greetable {
  override def hello() : String = "hello.";
}

hello.

こんな感じ。「extends AnyRef」は省略できるのだが、派生クラスを省略した場合には実装する最初の trait は extends で書かないとエラーになる。

class English() extends Greetable {
  override def hello() : String = "hello.";
}

こうなると Greetable が trait なのだか class なのだか分からないのでちょっと嫌な感じ。
ちなみに、 AnyRefは参照型の全オブジェクトの親クラス。
詳しくはこちら ( 日経ITプロ Scala言語を探検する 4 ) を参照。

Anyすべてのオブジェクトの親クラス
  AnyValすべてのプリミティブ型(Intとか)の親クラス
  AnyRefすべての参照型オブジェクトの親クラス(上以外)

上の例の override は省略することができる。Scala では、「すでに実装のあるメソッド」をオーバーライドする場合には override を指定しなければならない。もちろんオーバーライドでないのに override を指定するとエラーになるので、実装のない抽象メソッドを実装する場合にも間違い防止に付けておいたほうがいい。

trait は実装を持つこともできる。

...

trait Greetable {
  def hello() : String = "hello.";
}

class English() extends AnyRef with Greetable {
}

hello.

もうこうなると 抽象 class でも trait でもどちらでもよい気がしてくる。
ただ、これはこれで便利で、汎用的な機能をいろいろ trait に実装できるので無駄な実装がかなり減る気がする。

object TraitSample {
    def main(args : Array[String]) {
        val eng : English  = new English();
        println(eng.hello());
        println(eng.bye());
    }
}

trait Greetable {
  def hello() : String = "hello.";
}

trait Byeable {
  def bye() : String = "bye.";
}

class English() extends AnyRef with Greetable with Byeable {
}

hello. bye.

もはや多重継承。実装を宣言している2つの trait が同じメソッドを持っている場合はどうなるのだろうか?
まず実装を持っている trait がひとつだけの場合には何も問題ない。普通に動く。

両方とも実装を持っていた場合にはコンパイルエラーになる。
上のコードで Greetable に Byeable と同じ bye() メソッドを定義するとこのようになる。

overriding method bye in trait Greetable of type ()String; method bye in trait Byeable of type ()String needs `override' modifier

override をつければいいのか? とはいっても両 trait とも何かを override しているわけではないので、trait 側にoverride をつけるわけにはいかない。というわけなので、実装するクラス側で override してやるしかない。
object TraitSample {
    def main(args : Array[String]) {
        val eng : English  = new English();
        println(eng.hello());
        println(eng.bye());
    }
}

trait Greetable {
  def hello() : String = "hello.";
  def bye() : String = "bye [Greetable].";
}

trait Byeable {
  def bye() : String = "bye [Byeable].";
}

class English() extends AnyRef with Greetable with Byeable {
  override def bye() : String = super.bye();
}

hello. bye [Byeable].

super で呼び出されたのは Byeable のほうだった。ちなみに、
...
class English() extends AnyRef with Byeable with Greetable {
  override def bye() : String = super.bye();
}

hello. bye [Greetable].

あと勝ちだった。

2012年7月7日土曜日

[Scala] 多重ループ

for文で多重ループ

    for (i<-1 to 2; j<-5 to 6) print(i + "-" + j + " ")
実行結果:
1-5 1-6 2-5 2-6

ふむ。後ろが先に回っている。
拡張For文形式。ついでに if 句をつけてみる。

    val a = Array(1, 2, 3, 4);
    val b = Array(6, 7, 8, 9);
    for (i <- a if i % 2 == 0; j <- b if j % 2 == 0)
      print(i + "-" + j + " ");
実行結果:
2-6 2-8 4-6 4-8


yield句をつけると返り値はどうなるのだろう。

    val a = Array(1, 2, 3, 4);
    val b = Array(6, 7, 8, 9);

    val result : Traversable[String] = 
        for (i <- a if i % 2 == 0; j <- b if j % 2 == 0) yield
          i + "-" + j + " ";
    println(result);
実行結果:
ArraySeq(2-6 , 2-8 , 4-6 , 4-8 )


ふつうにTraversableで受けれた。返り値まで多次元になるわけではないようだ。

[Scala] 値を返すFor文

久々にScala。
前回はフィルタ条件付きのFor文を見たので、今回は値を返すFor文を見てみる。

    val a : Array[Int] = Array(-1, 2, -3);
    val result : Array[Int] = for (i: Int <- a) yield i.abs;
    for (i <- result) print(i);

yield節をつけることでこのfor文は結果を返すようになる。yieldの後ろがブロック式(複文)の場合には最後の 文 が返る(ブロック式の値は最後の文の値になるのがScalaのルール).

実行結果:
123


Arrayの関数呼び出しを使って書く場合は Traversable#map を使う。
    val result2: Array[Int] = a.map((i : Int) => i.abs);
    for (i <- result2) print(i); 

実行結果:
123

省略して書くとこんな感じ。
    val result3 = a.map(_.abs);

例によって、独自クラスでfor yieldを使えるようにしてみる。

object ForYieldSample {
  def main(args: Array[String]) {
    val a : Array[Int] = Array(-1, 2, -3);
    val fey : ForEachYieldable[Int, Array[Int]] = new ForEachYieldable(a);
    val result : Array[Int] = for (i: Int <- fey) yield i.abs;
    for (i <- result) print(i);
  }
}

class ForEachYieldable [A, Repr <: Array[A] ](col: Repr) {
  def repr: Repr = col;
  def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
    println("Here is ForEachYieldable#map");
    val b = bf(repr)
    b.sizeHint(repr)
    for (x <- repr) b += f(x)
    b.result
  }
}
実行結果:
Here is ForEachYieldable#map
123

確かに ForEachYieldable#map が実行されている。
元の TraversableLike#map の実装では、
val b = bf(this)
b.sizeHint(this)
となっていたのだが、この ForEachYieldable 自身は Traversable を実装していないので、 実際のデータを保持しているrepr を引数に使っている。このように、map自体の実装で使わなければ ForEachYieldable 自身に foreach を実装する必要はない。

2012年7月6日金曜日

画像のキャプチャ

巷にはいろいろなキャプチャ用ツールがあるようなので調べれば便利なものがいろいろあると思うのだが、とりあえず手元にあるものでなんとかしてみた。

 ■Snipping Tool 

Windows7 プリインストール済みのツール。アクセサリに入っている。
手軽でPNGでも保存できるのだが、減色ができないのでサイズが大きくなってしまう。

 ■IrFanView 

普段ビューアーとして使っている IrFanView なのだがキャプチャ機能がついている。ショートカットは「C」。
キャプチャ機能から直接ファイルに保存することができて、PNG出力する際にはPNGOUTプラグインが使えるのだがうまく減色してくれないみたい。

仕方がないので一度メインWindowに取り込んでから、Save for Webプラグインを使って16色に減色して保存。これでサイズはかなり小さくなるし、写真などをキャプチャするので無ければこれで十分。

2012年7月5日木曜日

[ドリトル] 再起呼び出しでフラクタル図形を描く

Dolittleで定義するメソッドは再起呼び出しをすることができる。
ということで早速フラクタることにする。まずはコッホ曲線
t1 = Turtle!create.
t1:koch = [
  | level width ; newWidth |
  [level <= 0 ] ! then [
     self ! (width) forward.
    ] else [
     newWidth = width / 3.
     self ! (level - 1) (newWidth) koch.
     self ! 60 leftturn.
     self ! (level - 1) (newWidth) koch.
     self ! 120 rightturn.
     self ! (level - 1) (newWidth) koch.
     self ! 60 leftturn.
     self ! (level - 1) (width - 2 * newWidth) koch.
   ] execute. 
].
t1 ! 2 500 koch.
...
t1 ! 6 500 koch.