フユノスフィアに行ってきた

少し前になるけれども、2月11日にZepp Tokyoであった新居昭乃のコンサート「フユノスフィア」に同僚のお誘いで行ってきた。
とても新曲が多かったのと、かなりMCが少なかったので、前回行ったときに比べると印象の違うライブだった。
今回はコンサートホールではなく、ライブハウスに椅子だったのだけれども、衝撃を受けたのが観客が皆動かない。どうしたことか、バスドラムの音も高らかに響いているのに動かない。静止している。ヘッドバンギングするような曲は皆無とはいえ、曲にはリズムがあるし、それに自然に体は動いてしまうものだと思っていたけれども、このライブの観客は動かなかった。観入っている、とでも表現すれば良いのかな。わからないけれど、個人的にはかなり驚いた。
いつもの通り癒してくれるキャラクタなのでライブは良かった。個人的な望みとしては、アンプラグドライブをやって欲しい。電子音の爆音とはまた違った素敵なライブになるのではないかと思う。

「デバッガによるx86プログラム解析入門」を読んだ

デバッガによるx86プログラム解析入門

デバッガによるx86プログラム解析入門

Digital Travesiaのうさぴょん氏によるプログラム解析本。
デバッグツールの使い方が画面キャプチャなども含めて大いに紙面を使っていたので(それこそスクロールバーとかツールバーとかの解説まで)、そういう書籍名の方がいいのではないかと少し思った。とはいえ、書籍前半の基本的なコンピュータへの命令の仕組みやアセンブリ言語については、非常に簡単に書かれていて本当の入門者にも取っ付きやすそうな印象だった。
上記サイトの情報をみても良くわからない人が読者ターゲットなイメージ。

Yahoo! Topics BarをFirefox3に対応させた

Yahoo! Topics Bar

2007年に作ったものだけれども、ずっとFirefox2までしか動かないままになっていたので、やっとFirefox3に対応した。
Yahoo!のトップページをチェックするほどでも、ましてYahoo!ニュースのRSSを追いかけたいほどではないけれど、Yahoo!トップページに表示されるような注目のトピックスくらいは消極的に表示されてたらみるかも、という人におすすめです。ステータスバーにリンクが表示されるだけで、クリックするとYahoo!のページに飛ぶことができます。クリックすると文字が灰色になり、より消極的になります。10分おきに更新を確認して新しいトピックがあるとリンクが入れ替わります。
Firefox3に対応していなかった理由は、install.rdfのバージョン書き換えるだけで動くかと思ったら動かず、原因を調べようと思いつつ今に至っていた。Firefox 3 安全な更新のために更新情報定義に署名するをみて対応したら問題なく動くようになった。id:higeponさんに感謝。

auブラウザで入力したテキストが消失する問題の再現方法

au端末でモバイルサイトを見ているときに、テキストフィールド(テキストエリア)に文字を入力して「OK」を押したのに、せっかく入力した文字が消えてしまうことがある。
これはコンテンツ読み込み中に入力された文字をブラウザが受け付けないのが原因みたい。要するに、画面表示された瞬間にすぐテキストフィールドをクリックして入力画面を開いて入力すると、確実に入力文字が消失する。現象を実験で確認しているだけで仕様かどうかなどはわからないけれども。
解決方法は通信が終わるまで待つくらいしか今のところ思いつかない。
auブラウザでクリアを長押しするとau oneトップに移動すると並んでauブラウザの嫌いなところ。

「今はもうない」を読んだ

今はもうない (講談社ノベルス)

今はもうない (講談社ノベルス)

途中で読むのを止めてしまっていたので非常に時間がかかったけれども、最近読み終えた。
感想は、もうなんというのか、文章の一行は怖いなというか、すっかりやられたというか、何を書いてもネタバレになるので書けない。密室よりもよほどこの小説自体の方がトリッキーだった。

家でステーキ

値段の割に良い肉が売っていたので、ステーキを焼いてみることにした。
DSCF2206
DSCF2206 posted by (C)cloned
実家で父親がやっていたのを思い出しながら、まずは塩と胡椒を両面にかける。塩は食卓塩ではなく粗塩。
DSCF2207
DSCF2207 posted by (C)cloned
焼き加減は外がカリっとして中がとろりとした状態を目指してみた。ただ、後で食べてみてわかったけれども、もう少し強火にしないとだめだった気がする。カリっとの部分が不十分だった。いつも父親がやっているようにそのまま包丁であつあつのうちに切ってお皿に盛りつける。
DSCF2208
DSCF2208 posted by (C)cloned
皿に盛ったらこんな感じ。まぁまぁの焼き加減。
DSCF2209
DSCF2209 posted by (C)cloned
醤油でいただいた。おいしい。反省は焼き加減と、買ってきた粗塩がかなりさらさらしていてうまくかけることができなかった。結果、少々塩の味がきつすぎた。あと、最大の反省点は、写真を撮っていたら食べるときに冷めていた。今度から気をつけよう。

ちなみに、昨日の夕飯はキノコ鍋にしてみた。
DSCF2189
DSCF2189 posted by (C)cloned
水炊きのキノコ具バージョン。鍋には水に昆布だけいれている。野菜がないのも寂しいから菊菜(全国的には春菊と言うのかな)を買ってきた。
DSCF2201
DSCF2201 posted by (C)cloned
一人で鍋やると量が問題。半分サイズのお豆腐とかないのかなぁ。ポン酢でおいしくいただいた。
DSCF2198
DSCF2198 posted by (C)cloned
ギネスのグラスを持っていないのでニュートンのグラスを代用。それにしてもきれいな泡だ。
DSCF2190
DSCF2190 posted by (C)cloned

ショコラブルワリーの生を飲んだ

※それぞれ数量限定

1月30日(金)〜サッポロビール博物館、サッポロビール園ガーデングリル、サッポロファクトリー内ビヤケラー札幌開拓使
2月 7日(土)〜14日(土) 恵比寿麦酒記念館

サッポロビール | ショコラブルワリー

本日が生を飲める最終日というたれこみがあったので、飲みに行ってきた。カメラを持って行くのを忘れたので写真がないのが残念だけど。
香りはそのままチョコレート。とてもチョコレート。飲んでみると炭酸は弱めで甘すぎない上品な味が口に広がる感じがした。恵比寿麦酒記念館が行列になっているという異常事態のため、一杯しか飲まなかったけれども、非常に満足。
缶のインターネット販売を見逃してしまっていたので、また通常販売があるときには是非購入したい。

話は違って、先日はギネスとヱビスのハーフを飲んだ。
ザ・リアルハーフ
ザ・リアルハーフ posted by (C)cloned
ザ・リアルハーフ
ザ・リアルハーフ posted by (C)cloned
普通のハーフアンドハーフと違って色が明確にわかれている。ギネスを先に入れて泡ができたところにヱビスを足すものかと思っていたけれども、泡が完全にヱビスのものだった。やや、ギネスの味が負けてしまっていて、ちょっと黒が入っている金ヱビスという印象だった。

昨日はうしとらでバレンタインカレーを食べた。
うしとら モツ&チョコレートビールカレー
うしとら モツ&チョコレートビールカレー posted by (C)cloned
愛がモツ、ということでモツ入りのチョコレートビールカレー。こんな組み合わせのカレーは世界広しといえどここでないと食べられないだろう。とてもおいしかったけど、辛みが強いのが個人的に苦手だったので、もう少しご飯たっぷりでも良かった感じ。一般的な辛みが大丈夫な人には絶品だったのではないかと思う。なお、本日もモツをさらに増やしたカレーがまだあるとのこと。

ほうれん草サラダ

本日の夕飯。自分で用意する夕飯が最近どう考えても居酒屋になっている。
ほうれん草サラダ
ほうれん草サラダ posted by (C)cloned
前回書いたベビーリーフサラダのベビーリーフの部分をほうれん草一色にしたのと、下北沢のビアバー「うしとら」のベビーリーフサラダを参考に(うしとらがどうしているかを直接聞いたわけではないので、あくまでも推測)、生ハムを乗せるまえに少しイタリアンドレッシングをかけたのと、生ハムのうえから粉チーズをふりかけた。前回よりもかなりパワーアップしておいしい。
写真に載っているあとのメニューは、ゆでたソーセージにマスタードと、ちくわをお醤油で。サラダのおかわりがあるので、多分大丈夫だけど、量的に足りないようだったらカマンベールチーズが控えている。

VBScript(WSH)の基礎とファイル読み書きや正規表現を使う

UNIX系のシェルスクリプトでは簡単にできることでも、Windowsのバッチファイルではできないことが非常に多い。そこで、Windowsの場合はWSHを利用することになる。かなり基本的すぎるところから、よくやりそうなテキスト処理などの例をメモがてら書いてみる。

VBScript

VBScriptはMicrosoft Visual Basic Scripting Editionの略で、Windowsで動くスクリプト言語。WSHはWindows Script Hostの略で、Windows上でスクリプト言語を動作させる実行環境。VBScriptの他にJScriptも動作する。サーバサイドの場合はASP(Active Server Pages)上でVBScriptを動作させることができる。

実行方法とHello World

vbsでファイルを保存。ダブルクリックで実行できる。Hello Worldは次の通り。

WScript.Echo "Hello World"

GUIからダブルクリックして実行した場合には.vbsがWScript.exeが関連付けされているため、ダイアログにHello Worldと表示される。コマンドプロンプトから実行する場合にはCScript.exeを利用する。コマンドは次のようになる。

C:\Path\To>CScript test.vbs
Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Hello World

WScript.Echoを利用しない方法としてMsgBox関数を使うこともできる。ただし、MsgBoxを利用するとコマンドプロンプトから実行してもGUIのダイアログが起動するので注意。

MsgBox "Hello World"

変数名やプロシージャ名、ステートメントなど大文字小文字の区別がないため、MsgBoxはMSGBOXなどと書くことができるが、慣例的にステートメントは大文字始まりのアッパーキャメルケースで書かれることが多い。

コメントアウト

行の先頭に’(シングルクォート)を付ける。

'WScript.Echo "Hello World"

複数行コメントはサポートされていない。

変数宣言

Dimを使って変数宣言を行う。JavaScriptのvarと同義だと思われる。Dimによって宣言された変数はスコープの外から利用することができない(Subプロシージャについては後述)。

Sub Hoge()
    Dim str
    str = "inner"
    WScript.Echo str
End Sub

Dim str
str = "outer"
WScript.Echo str
Hoge
WScript.Echo str

出力結果は「outer」「inner」「outer」となる。次のようにSubプロシージャ内のDim宣言を省略すると、外部スコープのDimが利用されるため、変数が上書きされる。

Sub Hoge()
'    Dim str
    str = "inner"
    WScript.Echo str
End Sub

Dim str
str = "outer"
WScript.Echo str
Hoge
WScript.Echo str

よって、この場合の出力結果は「outer」「inner」「inner」となる。

Dimによる変数宣言を省略しても暗黙に宣言されるためエラーにならない。変数宣言のない変数の利用をエラーにしたい場合は「Option Explicit」を利用する。次のコードはエラーとなる。

Option Explicit
x = 0

詳しくはDim ステートメントを参照のこと。

文字列結合

&を使って結合する。

WScript.Echo "Hello" & " " & "World"

改行を使う場合にはvbCrLf(CRLF)やvbCr(CR)、vbLf(LF)が利用できる。

WScript.Echo "Hello" & vbCrLf & "World"

これらの定数はConstantsクラスに属していてどこからでも参照することができる。
詳しくはConstants フィールドを参照のこと。

配列

配列は宣言時に()を付けて宣言する。

Dim ary(2)
ary(0) = "A"
ary(1) = "B"
WScript.Echo ary(0)
WScript.Echo ary(1)

出力結果は「A B」と表示される。Array関数を使って代入することもできる。次は前述と同様の挙動となるが、宣言時に()を付けて宣言することはできない。

Dim ary
ary = Array("A", "B")
WScript.Echo ary(0)
WScript.Echo ary(1)

オブジェクトの代入

通常の文字列や数値は変数に=演算子で代入することができるが、オブジェクトへの参照を代入する場合にはSetステートメントを利用する必要がある。オブジェクトのコピーではなくオブジェクトの参照が代入される。

Dim re
Set re = New RegExp

詳しくはSet ステートメントを参照のこと。

If文

If文は次の通り。

If condition Then

[statements]

[ElseIf condition-n Then

[elseifstatements]] . . .

[Else

[elsestatements]]

End If

If…Then…Else ステートメント

比較するときの演算子が「==」ではなく「=」であることに注意。「If hoge = “” Then」のようになる。また、否定の場合はIf Notを利用するので「If Not hoge = “” Then」のようになる。

繰り返し文

回数を指定して繰り返す場合はFor…Nextを使う。

Dim i
For i = 1 To 10
    WScript.Echo i
Next

出力結果は「1」〜「10」となる。
配列などのコレクションを繰り返す場合はFor Each…Nextが便利。

Dim strings(3), str
strings(0) = "A"
strings(1) = "B"
For Each str In strings
    WScript.Echo str
Next

出力結果は「A」「B」となる。
特定の条件で終了させる場合にはDo…Loopを使う。

Dim i
i = 0
Do Until i = 3
    WScript.Echo i
    i = i + 1
Loop

出力結果は「0」「1」「2」となる。

関数

値を返さないプロシージャはSub、値を返すプロシージャはFunctionとして定義する。
Subは値を返さないけれど、引数を参照で渡すことができる(デフォルトでは参照渡し)。値渡しにする場合はByValを付ける。明示的に参照渡しを指定する場合はByRefを付ける。

Sub Hoge(a, ByVal b, ByRef c)
    WScript.Echo a
    WScript.Echo b
    WScript.Echo c
End Sub
Hoge "A", "B", "C"

出力結果は「A」「B」「C」となる。呼び出すときに「Hoge(“A”, “B”, “C”)」というように括弧を使うとエラーになるので注意。
Functionプロシージャも引数はSubプロシージャと同様にデフォルトは値渡しで、変更する場合はByValを付ける。

Function Hoge(a, ByVal b, ByRef c)
    WScript.Echo a
    WScript.Echo b
    WScript.Echo c
    Hoge = "D"
End Function
WScript.Echo Hoge("A", "B", "C")

出力結果は「A」「B」「C」「D」となる。戻り値はreturnを使わずにFunctionプロシージャ名に代入する。呼び出しはSubプロシージャと異なり括弧を使う。
ややこしいのが、戻り値を受け取らないFunctionプロシージャはSubプロシージャとみなされる模様。

Function Hoge(a, ByVal b, ByRef c)
    WScript.Echo a
    WScript.Echo b
    WScript.Echo c
    Hoge = "D"
End Function
Hoge("A", "B", "C")

上記は戻り値を受け取っていないのでSubプロシージャとみなされ、括弧を付けて呼び出しているのでエラーになる。ただ、完全にSubプロシージャなわけでもなくてFunctionをSubに置き換えると「Hoge = “D”」の行でエラーになる(Subプロシージャは戻り値を持つことができない)。
アクセス修飾子を使うこともできるけれどここでは省略。
詳しくは、Sub ステートメントFunction ステートメントを参照のこと。

日付を利用する

日付を表すオブジェクトがいくつか存在する。

Dim d, n, t
d = Date()
n = Now()
t = Time()
WScript.Echo d
WScript.Echo n
WScript.Echo t

出力結果は上から「yyyy/MM/dd」「yyyy/MM/dd hh:mm:ss」「hh:mm:ss」の形式になる。一つ一つを分解して取得する場合はそれぞれに対応した関数を使用する。

Dim d, t
d = Date()
t = Time()
WScript.Echo Year(d)
WScript.Echo Month(d)
WScript.Echo Day(d)
WScript.Echo Hour(t)
WScript.Echo Minute(t)
WScript.Echo Second(t)

出力結果は上から「年」「月」「日」「時」「分」「秒」となる。
日付の計算にはDateAddなどを利用する。詳しくはDateAdd 関数を参照のこと。

ディレクトリのファイル一覧を取得

ファイルを操作するにはCreateObjectでScripting.FileSystemObjectを呼び出して利用する。オブジェクトなのでSetステートメントで代入する。ディレクトリのファイル取得はgetFolderを使ってフォルダオブジェクトを呼び出してからFilesを使って取得する。

Dim fso, dir, file
Set fso = CreateObject("Scripting.FileSystemObject")
Set dir = fso.getFolder(".")
For Each file In dir.Files
    WScript.Echo file.Name
Next

Scripting.FileSystemObjectは実際のファイルリソースではないようなのでClose処理がない。ただし、ファイルストリームを開いた場合などではClose処理にてフラッシュされる。
単一のファイルを取得する場合はGetFileを使う。取得できるのはオブジェクトで、代表的なプロパティの参照は次のようになる。

Option Explicit
Dim fso, file
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.GetFile("test.vbs")
WScript.Echo file.Name             ' ファイル名
WScript.Echo file.Drive            ' ドライブ名
WScript.Echo file.ParentFolder     ' 親フォルダ
WScript.Echo file.Path             ' パス
WScript.Echo file.Size             ' サイズ
WScript.Echo file.Type             ' 種類
WScript.Echo file.Attributes       ' 属性
WScript.Echo file.DateCreated      ' 作成日
WScript.Echo file.DateLastAccessed ' 最終アクセス日
WScript.Echo file.DateLastModified ' 最終更新日

ファイルを読み込む

OpenTextFileを使って読み込む。第一引数にファイル名、第二引数にモード(1=読み取り専用、2=書き込み専用、3=追記)、第三引数にファイルが存在する場合に新規作成するかどうか(作成する場合はTrue)。

Dim fso, reader
Set fso = CreateObject("Scripting.FileSystemObject")
Set reader = fso.OpenTextFile("test.vbs", 1, False)
Do Until reader.AtEndOfStream
    WScript.Echo reader.ReadLine
Loop
reader.Close()

出力結果は一行ずつ読み込まれた値になる。

ファイルを書き込む

ファイルの読み込みとほぼ同じで、引数を変更するのと、WriteLineで一行書き込むことができる。

Dim fso, writer, i
Set fso = CreateObject("Scripting.FileSystemObject")
Set writer = fso.OpenTextFile("write.txt", 2, True)
For i = 1 To 10
    writer.WriteLine i
Next
writer.Close()

出力されたファイルの内容は改行区切りで「1」〜「10」となる。
追記にする場合は「fso.OpenTextFile(“write.txt”, 8, True)」というようにOpenTextFileの第二引数を8に変更する。

文字列を区切り文字で配列にする

Splitを使う。

Dim strings, str
strings = Split("A,B,C", ",")
For Each str In strings
    WScript.Echo str
Next

出力結果は「A」「B」「C」となる。

正規表現を使ってパターンに一致するか調べる

Newを使ってRegExpオブジェクトを取得する。パターンはRegExpオブジェクトのPatternプロパティに代入する。

Dim re
Set re = New RegExp
re.Pattern = "^A.*"
If re.Test("ABC") Then
    WScript.Echo "matched"
End If

大文字小文字を無視する場合はIgnoreCaseにTrueを代入する。

re.IgnoreCase = True

最初の一致のみではなく、文字列全体を検索対象にする場合にはGlobalにTrueを代入する。

re.Global = True

正規表現を使って一致する文字列を取得する

RegExpオブジェクトのExecuteを使う

Dim re, matches
Set re = New RegExp
re.Pattern = "^A.*"
Set matches = re.Execute("ABC")
If matches.Count > 0 Then
    WScript.Echo matches(0)
End If

出力結果は「ABC」となる。

正規表現を使ってキャプチャした文字列を取得する

Itemプロパティを利用してSubMatchesを取得する。

Dim re, matches
Set re = New RegExp
re.Pattern = "^([A-F]+)_([A-F]+).+"
Set matches = re.Execute("ABC_DEF_GHI")
If matches.Count > 0 Then
    WScript.Echo matches.Item(0).SubMatches.Item(0)
    WScript.Echo matches.Item(0).SubMatches.Item(1)
End If

出力結果は「ABC」「DEF」となる。

正規表現を使って文字列を置換する

RegExpオブジェクトのReplaceを使う。

Dim re, matches
Set re = New RegExp
re.Pattern = "^ABC_"
WScript.Echo re.Replace("ABC_DEF_GHI", "XXX_")

出力結果は「XXX_DEF_GHI」となる。

正規表現を使って文字列を置換する(後方参照)

RegExpオブジェクトのReplaceを使って置換文字列中に$数字の形式で参照する。

Dim re, matches
Set re = New RegExp
re.Pattern = "^([A-Z]{2})(.*)"
WScript.Echo re.Replace("ABCDE", "XX$2")

出力結果は「XXCDE」となる。

まとめ

Windowsでもそれなりにちゃんとシェルスクリプトみたいなものを簡単に作ることができる。バッチファイルで無理やり頑張らずにVBScriptやJScriptの利用を検討すると良い。

関連: Windowsバッチのかゆいところメモ