このページの記事一覧
● 2012年8月31日金曜日 - [Scala] getter / setter
● 2012年8月29日水曜日 - [ドリトル] ドリトルのマウス
● 2012年8月28日火曜日 - [Scala] Tuple
● 2012年8月27日月曜日 - [Scala] ””” (トリプルクォート)
● 2012年8月26日日曜日 - [AppEngine] JDO でデータストアを使う
● 2012年8月25日土曜日 - [AppEngine] JDO でデータストアを使う(準備編)
● 2012年8月24日金曜日 - [AppEngine] AppEngine で Servlet+JSP を使う。
● 2012年8月22日水曜日 - [ドリトル] プロパティや命令の探索
● 2012年8月21日火曜日 - [AppEngine] デプロイしてみる
● 2012年8月19日日曜日 - [AppEngine] Google App Engine を使ってみる。
● 2012年8月18日土曜日 - [Scala] Eclipse Juno + Scala IDE
● 2012年8月17日金曜日 - Eclipse で Java のコードアシストが効かない。
● 2012年8月16日木曜日 - [ドリトル] サイクロイド曲線
● 2012年8月15日水曜日 - [ドリトル] 放物線の反射
● 2012年8月14日火曜日 - [ドリトル] 花火
● 2012年8月13日月曜日 - [Scala] カリー化
● 2012年8月12日日曜日 - [Scala] 部分適用
● 2012年8月11日土曜日 - [Blogger] 未来の投稿
● 2012年8月10日金曜日 - [Blogger] nbsp
● 2012年8月9日木曜日 - [Blogger] 記事一覧
● 2012年8月8日水曜日 - [Blogger] テンプレート中で現在表示されているページのタイプを判別する。
- [Blogger] Tableのスタイル
● 2012年8月7日火曜日 - [Blogger] Bloggerのテンプレートに関する情報源について
● 2012年8月6日月曜日 - IrfanView での日本語フォルダ問題
● 2012年8月5日日曜日 - [Scala] tryBreakable
● 2012年8月4日土曜日 - [Scala] Continue
● 2012年8月3日金曜日 - [Scala] break
● 2012年8月2日木曜日 - [Blogger] テンプレートのバックアップとリストア
● 2012年8月1日水曜日 - [Blogger] カテゴリ別記事一覧をつけてみた

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] カテゴリ別記事一覧をつけてみた

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

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