2012-04-29

オブジェクト指向とイデア論

HTML→CSS→JavaScript(挫折)→CGI(Perl)→PHP,VB ... と、
元はホームページ作りたかったので、そこから色々つまみ食いしては忘れ、
忘れた頃になにかプログラム組みたくなったりして現在に至るわけですが、
とりわけJavaScriptには苦い思い出があります。

当時はIE6、ネットスケープとかだったのでステータスバーに文字を流すとかやってた牧歌的な時代です。
JavaScript本を一冊買ったもののメソッドだのプロパティだの意味が分からない。
今にして思えば、JavaScript自体のオブジェクト、ブラウザのオブジェクト、 DOM なんかがごっちゃになってたんだなと。

全体は見通せないし、デバッグの仕方も分からないし、労力の割りに大したこと出来なくて投げたわけです。
ここでオブジェクト指向的なものに苦手意識が植え付けられます。

その後、CGI(Perl)を改造したりしてるとモジュールに出会う。
モジュールはオブジェクト指向で書かれてるらしいので苦手意識がありつつも調べてみる。
やっぱりここでも挫折するわけですが、すごく印象に残っているのがこの記事。

@IT:オブジェクト指向の世界(10) プラトン編-イデア論とクラス/インスタンス

読んだ当時はさっぱりでしたが、オブジェクト指向って哲学由来なんだなと。

そこで自分のプログラミングの入り口たる HTML と CSS に戻りますが、
文章と装飾の分離という考え方は 「本質」 と 「本質でないもの」 の分離で
哲学っぽいなと思っていたので、非常に印象深いわけです。


プラトンのイデア論

プラトンは「無知の知」で知られるソクラテスの弟子。
ソクラテスは倫理を追求した人なので、プラトンもかなりその影響を受けてます。
そのせいなのかプラトンは理想主義的な印象。

イデア論とは、端的に言えばこういうことです。
ものには イデア(idea) という真の原型が存在する。
この世にあるものは イデア のコピーに過ぎない。

この考え方がオブジェクト指向に似てるわけです。

イデア - クラス
イデアのコピー - インスタンス(オブジェクト)

似てるというよりそのまんまですね。


抽象と具体

一度クラスを使ったプログラムを作ってみれば、その後は理解が進むものです。
一方で、humanクラスからbaker、animalクラスからdogを作るみたいな例は なんで分かりづらいのか。

それは、クラスが抽象化されたものだから、じゃないかと。

抽象化というのは、対象の特徴、要素を抜き出すことです。
抽象化されたクラスを説明するのにクラスから入ると、 具体的なもの(オブジェクト)がイメージしにくい。

むしろ、複数のオブジェクトからクラスを作った方が、 抽象化のプロセスから考えても分かりやすいのでは。


プラトンの弟子のアリストテレスもイデア論はしっくりこなかったようです。
「実体が先にあって、それらを基にして人間が頭の中で抽象化して創りだしたものを
イデアと呼んでいるにすぎないというのが自然な考え方である」
アリストテレスは帰納的アプローチが好きなので
実体がなく検証しようがないイデアという概念は納得いかないのでしょう。

アリストテレスも、オブジェクトからクラスの方が分かりやすいタイプだと思いませんか。


PCは叡智の結晶

ハイテクの塊であるPCに古代ギリシャの哲学が生きている。
それだけ過去の賢人は普遍的なもの、本質に迫っていたんだなと感じます。

PCを通じて人類の叡智に触れられるなんて、PCはオモチャとして最高。
いろんな概念に触れられるオモチャなんて他にはそうないんじゃないでしょうか。


参考リンク

@IT連載 「オブジェクト指向の世界」
オブジェクト指向と哲学
ギリシア哲学への招待状

2012-04-28

可能性と蓋然性の違い

普段、なにげなく使ってる「可能性」という言葉。

「可能性が高い(低い)」 というのは間違っていて、
「蓋然性が高い(低い)」 と使うのが正しいとのこと。

可能性 は possibility、起こるか起こらないか、有るか無いか。
蓋然性 は probability、確からしさの度合い、確率。
「可能性がある(ない)」
「蓋然性が高い(低い)」
これが本来の使い方らしい。

そうはいっても普通は「蓋然性」っていっても通じないよね。
日銀のレポートぐらいでしか見たことないし。

英語に訳す場面だと使い分けないとまずいのでしょう。

日本語だと曖昧だけど、英語にすると明確に違う実感が湧くのは何ででしょうね?
プログラミングもいくつか違う言語をつまみ食いすると理解が進んだりしますし。
もしや、これは単に習熟度が低い(日本語含む)ということか!

概念と言語というテーマは面白いですね。
この面白さに中学の時、気付いていればなー。

2012-04-08

Bloggerのテンプレートをいじる

というエントリーを書きたかったがまたもや挫折・・・。
Blogger を始めたときも挫折して CSS をいじったぐらいで現在に至るわけです。
なんというかドキュメントがしょぼいんですよね。

さらに今はテンプレートが version2 になってますが、このドキュメントも見当たらない。
とりあえず分かったところまでまとめます。


コード

Blogger のテンプレートは XHTML にコードを埋め込む形式。
Movable Type の MTML に書き方が似てますね。
簡略化したテンプレートの一部はこんな感じ。
<div id='header-wrapper'>
 <b:section class='header' id='header'>
  <b:widget type='Header' id='Header1' expr:title='data:blog.title'>

   <b:includable id='main'>
    <h1 class='title'>
     <data:title/>
    </h1>
   </b:includable>

  </b:widget>
 </b:section>
</div>


<b:section>

テンプレートはいくつかの <b:section> を持ちます。

<b:section> の中に <b:section> は入れ子にできません。
<b:section> は <b:widget> しか持てません。
<b:section> は複数の <b:widget> を持てます。

<b:section> は <div> に置換されます。

属性 任意性 備考
id string 必須 一意の名前。
class string オプション よく使用されるクラス名は navbar, header, main, sidebar, footer など。
maxwidgets number オプション この section で使用できる widget の最大数。
指定しない場合、上限なし。
showaddelement 'yes' | 'no' オプション レイアウトページで [ガジェットを追加] リンクを表示するかどうか。
growth 'horizontal' | 'vertical' オプション この section 内の widget の並べ方。水平か垂直。


<b:widget>

<b:widget> は <b:includable> しか持てません。
<b:widget> には id='main' を指定した <b:includable> が1つ必要です。

<b:widget> は <div> に置換されます。

属性 任意性 備考
id string 必須 テンプレート内の widget の id は一意である必要があります。
widget の id は変更できません。
変更する場合は、一度 widget を削除して、新しく作成します。
type string 必須 widget の種類。
BlogArchive、Blog、Feed、Header、HTML、SingleImage、LinkList、 List、Logo、BlogProfile、Navbar、VideoBar、NewsBar など。
locked 'yes' | 'no' オプション ロックされた widget はレイアウトページで移動、削除できません。
title string オプション レイアウトページでの widget の表示タイトル。
指定しない場合、'List1' などのデフォルトのタイトルが使用されます。
pageType 'all' | 'main' | 'item'| 'archive' オプション 指定した表示タイプにのみ表示されます。
mobile 'default' | 'yes' | 'no' | 'only' オプション widget をモバイルで表示するかどうかを指定します。
default を指定すると、モバイルでは Header、Blog、Profile、PageList、AdSense、Attribution が表示されます。


<b:includable> <b:include>

<b:includable id='main'> はデフォルトで展開されます。

その他の id 属性が指定された <b:includable id ='***'> は関数みたいなもので
<b:include name='***'> を使って呼び出して使います。

要は <b:includable> の中にいろいろとコードを書いていくわけです。

includable
属性 任意性 備考
id string 必須 一意の名前。
var string オプション include から渡される引数を受け取る変数名。
include
属性 任意性 備考
name string 必須 一意の名前。
data string オプション includable に渡す何らかのデータ構造。
(ex. blog, blog.title, posts, feedData ...)

<b:include> を使うとこんな感じになります。
<div id='header-wrapper'>
 <b:section class='header' id='header'>
  <b:widget type='Header' id='Header1' expr:title='data:blog.title'>

   <b:includable id='main'>
    <h1 class='title'>
     <b:include name='title'/>
    </h1>
   </b:includable>

   <b:includable id='title'>
    <b:if cond='data:blog.url == data:blog.homepageUrl'>
     <data:title/>
    <b:else/>
     <a expr:href='data:blog.homepageUrl'><data:title/></a>
    </b:if>
   </b:includable>

  </b:widget>
 </b:section>
</div>
<b:include name='title'/>

<b:includable id='title'>
  ...
</b:includable>
を呼んでるのが分かるでしょうか。
前はこの <b:includable> が分からなくて挫折しました。

また、 <b:includable> は次のようにして引数を受け取ることも出来ます。
<b:includable id='main'>
 <b:include name='post' data='blog'/>
</b:includable>

<b:includable id='post' var='arg'>
 <data:arg.title/><br/>
</b:includable>


<data:***/>

<data:***/> タグはブログの各データを展開するだけなので、これは簡単ですね。
<data:blog.title/>
<data:blog.url/>
XHTML タグの中では書き方が違うので注意が必要です。
この書き方はダメです。
<a href='<data:blog.homepageUrl>'> TITLE </a>
XHTML タグの属性の前に expr: を付けて data:*** とします。
なぜか expr: はドキュメントに載ってません。
<a expr:href='data:blog.homepageUrl'> TITLE </a>

グローバルに参照できるデータ
<data:blog.title/> のように参照します。

この他にもブログのソースの一番下の方の
_WidgetManager._SetDataContext() 内に
参照できるデータが JavaScript のオブジェクト形式で書いてあります。

blog
属性 備考
title string ブログのタイトル。
homepageUrl string ブログの URL。
http://*****.blogspot.jp/
canonicalHomepageUrl string ブログの URL。
http://*****.blogspot.com/
pageType 'index' | 'item' | 'archive' | 'static_page' 現在のページの種類。
pageTitle string 現在のページのタイトル。
url string 現在のページの URL。
http://*****.blogspot.jp/*****
canonicalUrl string 現在のページの URL。
http://*****.blogspot.com/*****
encoding string ブログで使用する文字エンコード。
isMobile bool モバイルかどうか。
feedLinks string フィードの<link>タグ(XHTML)。

各 widget 内で参照できるデータ
widget の type や属性は追加、統廃合されてるようなので
ここに載ってなかったり、使えなかったりするかもしれません。

Header
属性 備考
title string ブログのタイトル。
description string ブログの説明。
mobile bool モバイルかどうか。
useImage bool ヘッダーに背景画像を使うかどうか。
imagePlacement 'BEHIND' |
'REPLACE' |
'BEFORE_DESCRIPTION'
背景画像の位置。
sourceUrl string 背景画像の URL。
backgroundPositionStyleStr string 背景画像の backgroundPosition。
widthStyleStr string 背景画像の幅。
height string 背景画像の高さ。
width string 背景画像の幅。

Blog
属性 備考
olderPageTitle string 過去の投稿ページへのリンクのタイトル。
olderPageUrl string 過去の投稿がある場合、その投稿の URL。
newerPageTitle string 新しい投稿ページへのリンクのタイトル。
newerPageUrl string 新しい投稿がある場合、その投稿の URL。
     
commentLabel string コメント数を表示するために使用するフレーズ (例"コメント数")。
authorLabel string 投稿者が誰かを示すために使用するフレーズ (例"投稿者")。
timestampLabel string 投稿時間を示すために使用するフレーズ (例"に投稿")。
postLabelsLabel string 投稿のラベルのリストを示すフレーズ (例"この投稿のラベル")。
backlinksLabel string 投稿のバックリンクを示すフレーズ (例"この投稿へのリンク")。
numPosts string 投稿数。
shareMsg string
homeMsg string homepage リンクのテキスト。
mobile bool モバイルかどうか。
desktopLinkUrl string desktopLink の URL。モバイル用?
desktopLinkMsg string desktopLink のテキスト。モバイル用?
mobileLinkUrl string mobileLink の URL。モバイル用?
mobileLinkMsg string mobileLink のテキスト。モバイル用?
     
defaultAdStart string Google AdSense
defaultAdEnd string Google AdSense
adCode string Google AdSense
adStart string Google AdSense
adEnd string Google AdSense
     
feedLinks list 現在のページのフィードのリスト。
- url string フィードの URL。
- name string フィードの名前 (例'投稿' や 'コメント' など)。
- feedType 'Atom' | 'RSS' フィードの種類。
- mimeType string フィードの MIME 形式。
     
posts list 現在のページのすべての投稿のリスト。
- dateHeader string この投稿の日付。この投稿がリストにおいてその日最初の投稿であった場合にのみ表示します。
- timestamp string この投稿のタイムスタンプ。 dateHeader とは異なり、これはすべての投稿に存在します。
- timestampISO8601 string この投稿の ISO8601 形式のタイムスタンプ。
- id string この投稿の ID 番号。
- url string この投稿の Permalink。
- link string この投稿の link。
- title string この投稿のタイトル。
- body string この投稿のコンテンツ。
- author string 投稿者のハンドル ネーム。
- authorProfileUrl string 投稿者プロフィールへの URL。
- thumbnailUrl string この投稿の画像のサムネイルの URL。
- snippet string この投稿のコンテンツの出だし部分。
- isDateStart bool その日最初かどうか。
- isFirstPost bool その日最初の投稿かどうか。
- hasJumpLink bool JumpLink (もっと読む)があるかどうか。
- jumpText string JumpLink のテキスト(例"もっと読む")。
- allowComments bool この投稿がコメントを許可している場合は 'True'。
- numComments string この投稿のコメント数。
- showThreadedComments bool スレッド式のコメントを表示するかどうか。
- showBacklinks bool この投稿のバックリンクを表示するかどうか。
- numBacklinks string この投稿のバックリンク数。
- addCommentUrl string この投稿の [コメントを追加] フォームの URL。
- addCommentOnclick string [コメントを追加] クリック時の JavaScript code。
- emailPostUrl string この投稿の [この投稿をメール送信] フォームの URL。
- editUrl string この投稿の [編集] フォームの URL。
- dummyTag string ダミータグ。
     
- labels list この投稿のラベルのリスト。
-- name string ラベルのテキスト。
-- url string このラベルが付いた投稿リストページの URL。
-- isLast bool このラベルがリストの最後かどうか (カンマを付けるのに役立ちます)。
     
- feedLinks list この投稿に特有のフィードのリスト (ブログ全体の feedLinks とは異なり、投稿のコメント用のフィードなどを含めることができます)。それぞれに次のものが含まれます。
-- url string フィードの URL。
-- name string フィードの名前 (例'投稿' や 'コメント')。
-- feedType 'Atom' | 'RSS' フィードの種類。
-- mimeType string フィードの MIME 形式。
     
- comments list この投稿のすべてのコメントのリスト (アイテム ページ上のみ)。
-- id string コメントの ID 番号。
-- body string コメントの本文。
-- timestamp string コメントが作成された時刻。
-- author string コメントの投稿者のハンドル ネーム、または '匿名'。
-- authorUrl string コメントが匿名でない場合、コメントの投稿者のプロフィールの URL。
-- deleteUrl string このコメントを削除するための URL。
-- isDeleted bool このコメントを削除するかどうかを指定します (削除されたコメントは、プレースホルダーに置き換えられます)。

BlogArchive
属性 備考
title string ウィジットのタイトル。
style 'MENU' | 'FLAT' | 'HIERARCHY' 表示形式。
     
data list アーカイブ ユニットのリスト。
- name string このアーカイブの期間の名前 (ex. "2006年8月")。
- url string この期間の投稿を含むページのリンク。
- post-count string この期間中の投稿数。

Feed
属性 備考
title string ウィジットのタイトル。
feedUrl string フィードの URL。
     
feedData list フィードのアイテムです。
- title string アイテムのタイトル
- str_published string アイテムが公開された時期
- published string アイテムが公開された時期 (秒単位)。
- str_updated string アイテムの最終更新日
- updated string アイテムの最終更新日 (秒単位)。
- author string アイテムの著者。
- summary string 可能な場合はアイテムの抜粋。
     
- alternate list このアイテムに関する詳細情報の提供元。
-- href string このアイテムの Permalink。
-- type string このアイテムのコンテンツ タイプ。

テキスト / HTML / JavaScript
属性 備考
title string ウィジットのタイトル。
content string ウィジットのコンテンツ。

Image
属性 備考
title string ウィジットのタイトル。
sourceUrl string 画像の URL。
width string 画像の幅、ピクセル単位。
height string 画像の高さ、ピクセル単位。
caption string 画像のキャプション。

LinkList
属性 備考
title string ウィジットのタイトル。
links list リンクのリスト。
- name string リンクのテキスト。
- target string リンクの URL。

List
属性 備考
title string ウィジットのタイトル。
items list アイテムのリスト。

Logo
属性 備考
fullButton string 選択した Blogger ボタンの URL。

Profile
属性 備考
title string ウィジットのタイトル。
userUrl string 投稿者のプロフィールの URL。
location string 投稿者のプロフィールの場所。
aboutme string プロフィールの "自己紹介" 情報。
displayname string 投稿者のハンドル ネーム。
     
photo list ユーザーのプロフィールの写真。
- url string 写真の URL。
- width string 写真の幅、ピクセル単位。
- eight string 写真の高さ、ピクセル単位。
- alt string 写真の "alt" テキスト。

Label
属性 備考
title string ウィジットのタイトル。
display 'list' | 'cloud' 表示形式。
     
labels list ラベルのリスト。
- name string ラベルのテキスト。
- count string このラベルが付いている投稿数。
- url string このラベルが付いている投稿を表示しているページへのリンク。
- cssSize string クラウド形式の文字のサイズ。

Gadget
属性 備考
title string ウィジットのタイトル。
gadgetSnippet
renderingUrl
nonSocialFragment
errorMessage

<data:***/> タグの詳細はドキュメントを参照してください。
レイアウト データ タグ - Blogger ヘルプ


<b:if> <b:else/>

if 文は特に説明はいらないでしょう。
else はありますが、else if はありません。
<b:if cond='条件式'>
 ...
</b:if>

<b:if cond='条件式'>
 ...
<b:else/>
 ...
</b:if>
<b:if cond='data:blog.url == data:blog.homepageUrl'>
 <data:title/>
<b:else/>
 <a expr:href='data:blog.homepageUrl'><data:title/></a>
</b:if>
現在の投稿がバックリンクを表示するように設定されている場合は true。
<b:if cond='data:post.showBacklinks'>

現在のページがアイテム ページ (投稿ページ) であるなら true。
<b:if cond='data:blog.pageType == "item"'>

ハンドル ネームが Fred でなければ true。
<b:if cond='data:displayname != "Fred"'>

現在の投稿に複数のコメントがあれば true。
<b:if cond='data:post.numComments > 1'>


<b:loop>

ループは var 属性に変数名、 values 属性にリストを指定します。
<b:loop var='i' values='data:posts'>
 <h2><data:i.title/></h2>
</b:loop>
また、 <b:include> を使って処理することもできます。
<b:loop var='p' values='data:posts'>
 <b:include name='EachPosting' data='p'/>
</b:loop>

<b:includable id='EachPosting' var='arg'>
 <data:arg.title/><br/>
</b:includable>


<b:skin>

CSS は <b:skin> タグの中に書きます。
<Variable> の name 属性に指定した名前を使って CSS に変数が使えます。
これはテンプレートデザイナーで簡単に変更できるという機能らしいです。

自分で使うだけというなら CSS ベタ書きで構いません。
しかし、ベタ書きの場合でも <b:skin> タグの中に書く必要があります。
<head>

<b:skin>
<![CDATA[
/*
 <Variable name="pgbgcolor"
  description="Page Background Color"
  type="color" default="#fff" value="#ffffff">
 <Variable name="pgtxtcolor"
  description="Page Text Color"
  type="color" default="#444" value="#444444">
*/

body {
 background: $pgbgcolor;
 color     : $pgtxtcolor;
 }
]]>
</b:skin>

</head>


<macro:> mexpr:

テンプレートの version2 では HTML5 対応?
<macro:> mexpr: も追加されてるのですが
ドキュメントが見当たらないのでよく分かりません。


参考サイト

レイアウト ガイド - Blogger ヘルプ
レイアウト用フォント タグとカラー タグ - Blogger ヘルプ
レイアウト用ページ要素タグについて - Blogger ヘルプ
レイアウト用ウィジット タグ - Blogger ヘルプ
レイアウト データ タグ - Blogger ヘルプ

Template of Doom
Bloggerテンプレートタグ一覧 - SNAPMAN
Blogger | egoblock
The Anatomy of a Blogger Layout (template) | fumbling in the dark

テンプレートデザイナーのHTML編集で過去記事一覧をサイドバーに出したい | Google グループ

Blogger の投稿フッターにはてなブックマーク件数を表示する方法
Bloggerのアーカイブページやラベルページで記事タイトル一覧を表示 :: Holiday Webmaster Blog

まとめるだけでお腹いっぱい。


- 追記 -

便利なところを見つけてしまった。
data: タグの値が見やすい。
blogger2ools

2012-04-05

バッチファイル入門

GUI に慣れてるととっつきにくいコマンドライン。
しかし、世の中には CUI しかないアプリケーションもあります。

毎回コマンドプロンプトから入力するのは大変ですが、
バッチファイルを作っておくとダブルクリックで実行できて便利。

今回は rtmpdump のバッチファイルを例に解説します。
::rtmpdump.bat

set rtmpdump="..\rtmpdump.exe"

%rtmpdump%^
 --rtmp     "rtmp://"^
 --tcUrl    ""^
 --app      ""^
 --playpath ""^
 --swfVfy   "http://"^
 --pageUrl  "http://"^
 --flashVer ""^
 --flv      ""


pause
exit


最初の行から解説していきますね。
::rtmpdump.bat

rem rtmpdump.bat
最初はコメント行です。
正式には rem のあとにコメントを書きます。

: はラベルの表記なのですが
:: はコメントの簡略表記として使われてるようです。
set rtmpdump="..\rtmpdump.exe"

%rtmpdump%^
次は変数 rtmpdump に値として rtmpdump.exe のパスをセットしてます。
フルパスでもバッチファイルからの相対パスでもOKです。

変数をコマンドとして展開する場合、スペースで区切られるので
パス名にスペースを含むときはダブルクォートで囲みましょう。

次に %rtmpdump% のように変数名を % で囲むと値が展開されます。

さて、rtmpdump にはこのあとオプションをいくつか渡す必要があります。
すると一行がえらく長くなって見づらいし、修正もしにくいので複数行に分けます。
単純に改行するとコマンドとして途切れてしまうので
改行を ^ (キャレット)でキャンセルします。
 --rtmp     "rtmp://"^
 --tcUrl    ""^
 --app      ""^
 --playpath ""^
 --swfVfy   "http://"^
 --pageUrl  "http://"^
 --flashVer ""^
 --flv      ""
先ほどの ^ (キャレット)を使ってオプションをこんな感じで書けます。
一行に書くより遙かに見やすいですね。

ここでも引数にスペースを含まない限り、 ダブルクォートで囲む必要はありませんが念のため囲ってます。

rtmpdump のオプションについてはドキュメントを読んでください。
pause
exit
ここはある意味肝です。

普通にバッチファイルをダブルクリックすると 実行後にコマンドプロンプトが閉じてしまうので
エラーが起きたのか成功したのかすら分かりません。
そこで、 pause を入れることで勝手に閉じるのを防げます。

exit はなくてもいいのですが、ここで終了するので このあとにコメントやメモを書いておけます。
オプションやヘルプなんかを貼っておくと便利ですね。

ここまで説明してなんですが、rtmpdump で検索して来たあなた。
RTMPExplorer を使った方が簡単ですよ。

@echo off
@echo off と書くと以後のコマンド入力が表示されなくなります。
出力だけ見たいときに書いておくとスッキリします。
rtmpdump のバッチでは変数展開をチェックしたいので書いてませんけど。
%rtmpdump%^
 -オプション^
 > output.txt 2>&1
出力を保存したいときはこんな感じでリダイレクトを使って、テキストファイルに書き出します。
リダイレクトの詳細は以下を参照してください。
コマンド リダイレクト演算子を使用する - microsoft


バッチパラメータ

バッチファイルは引数を使うことも出来ます。
%0 はバッチファイル名、%1 ~ %9 は引数で置換されます。

ドラッグアンドドロップしたファイル名は %1 になります。
@echo off
echo %1

pause
上のコードを C:\test.bat と保存してコマンドプロンプトから使う例です。
組み込みの環境変数 %date% を引数として渡してます。
C:\test.bat %date%

また、 %~(修飾子)(引数番号) とすると、ファイル名の一部を取り出したりできます。
@echo off

echo ファイル名
echo %~0
echo フルパス名
echo %~f0
echo ドライブ名
echo %~d0
echo パス名のみ
echo %~p0
echo ファイル名のみ
echo %~n0
echo 拡張子のみ
echo %~x0
echo ショートネーム
echo %~s0
echo ファイル属性
echo %~a0
echo ファイル日付
echo %~t0
echo ファイルサイズ
echo %~z0
echo.
echo ドライブ名 + パス名
echo %~dp0
echo ファイル名 + 拡張子
echo %~nx0
echo.

pause


日付・時間を使う

ファイル名などに日付・時間を入れたいこともありますね。
そんなときは、組み込みの環境変数 date、time を使います。

::datetime.bat
@echo off

echo 今日の日付
echo %date%
:: 2012/01/01

echo 現在時刻
echo %time%
:: 12:00:00.00

pause

ここで問題なのは / (スラッシュ)、 : (コロン) はファイル名に使えないことです。
要らないものは置換してしまいましょう。

書式は %変数名:置換対象文字列=置換後文字列% となります。
echo %date:/=%
:: 20120101

echo %time::=%
:: 120000.00

echo %date:/=%_%time::=%
:: 20120101_120000.00

このままで用が足りる場合もあるでしょうが、
細かく整形したい場合は抽出しちゃいましょう。

書式は %変数名:~m,n% (m,nは数字)となります。
m 文字目から n 文字を抽出します。
1番目の文字を 0 として数えることに注意。
m がマイナスの場合は、後ろから数えます。
set dt=%date%
set yyyy=%dt:~-10,4%
set mm=%dt:~-5,2%
set dd=%dt:~-2,2%

set date2=%yyyy%-%mm%-%dd%
echo %date2%
:: 2012-01-01

set tm=%time: =0%
set hh=%tm:~0,2%
set mm=%tm:~3,2%
set ss=%tm:~6,2%

set time2=%hh%-%mm%-%ss%
echo %time2%
:: 12-00-00

echo %date2%_%time2%
:: 2012-01-01_12-00-00

これで好きなように整形できますね。

補足しておくと、Windows2000では日付が
日 2012/01/01
のように曜日が頭に付くので、後ろから数えてます。

また、時間が1桁の場合
 1:00:00.00
のように頭にスペースが付くので 0 に置換します。


短く書きたい場合は
:: yyyy-mm-dd
echo %date:~-10,4%-%date:~-5,2%-%date:~-2,2%

:: Windows2000を考慮しない場合
echo %date:~0,4%-%date:~5,2%-%date:~8,2%

:: hh-mm-ss
set time2=%time: =0%
echo %time2:~0,2%-%time2:~3,2%-%time2:~6,2%



入門編としてはこれぐらい押さえておけばいいでしょう。
制御文やループを使いたいという方は参考サイトをどうぞ。


- 参考サイト -

コマンドライン リファレンス - microsoft
Windowsコマンドプロンプト基礎文法最速マスター - CX's Memo
バッチファイル基礎文法リファレンス - 学習ノート
連載:Windows 2000コマンドライン徹底活用 - @IT
バッチ・ファイル中で日付をファイル名に使用する - @IT

2012-04-04

Perl - WindowsでPerl

ワンライナー

ネットで見つけたワンライナーをコマンドプロンプトで使おうとすると
perl -e 'print "Hello, World!"'
Can't find string terminator "'" anywhere before EOF at -e line 1.
こんな感じでエラーが出て使えません。

引数はダブルクォートで囲わないとダメなので少し変更しないといけません。
# 内側のダブルクォートをエスケープする
perl -e "print \"Hello, World!\""

# qq 演算子を使う
perl -e "print qq{Hello, World!}"

# 内側のダブルクォートをシングルクォートに置き換える
perl -e "print 'Hello, World!'"

# q 演算子を使う
perl -e "print q{Hello, World!}"


perlへのショートカット

こんな感じでショートカットを作っておくと
ファイルをドラッグアンドドロップで実行できます。



バッチファイルでもできるのでお好きな方をどうぞ。
@echo off
cd /d "%~dp0"
cmd /k perl %1


UTF8を出力

現在では UTF8 でコードを書くのが主流ですが、
コマンドプロンプトの文字コードは CP932 なので
UTF8 で出力すると当然、文字化けします。

これは binmode で文字コードを CP932 にすれば大丈夫。
use strict;
use warnings;
use utf8;
binmode STDOUT => ':encoding(cp932)';

print "寿限無寿限無";
出力を UTF8 のまま得たい場合はテキストファイルに出力します。
use strict;
use warnings;
use utf8;
binmode STDOUT => ':utf8';

print "寿限無寿限無";
perl "C:\utf8.pl" > "C:\utf8.txt"
コマンドプロンプトの文字コードを UTF8 にする方法は
うまくいかない場合があるので、テキストファイルに出力した方が確実です。


秀丸でperl

秀丸マクロを覚えるのが面倒というあなたへ。
ちょこっと整形、置換、抽出したいときは 「その他 > プログラム実行」から perl が使えます。



ただ、これだと UTF8 でコードを書いた場合、shift-jis に変換されるのでうまくいきません。
この場合、下のように設定してください。
「Unicodeで標準入出力」は UTF-16 なのでチェックしません。



これは perl にファイル名を渡して cp932 で出力を受け取ります。
なのでファイルとして保存してから実行してください。
# サンプル
use strict;
use warnings;
use utf8;

binmode STDOUT => ':encoding(cp932)';
binmode STDERR => ':encoding(cp932)';

for my $line (<DATA>){
    chomp $line;
    print "僕と契約してよ、$line。\n";
}

__END__
うろぶち
きょうこ
まみ
まどか
さやか
ほむら
__END__ 以下は <DATA> で読み出せるので処理したいデータを貼り付けて
for なり while で回してゴニョゴニョします。

ちょろっとテキストを処理したいときなんか便利じゃないでしょうか。

2012-04-03

Perl - PACKAGEはブロックスコープじゃない

あまり使わないかもしれませんが、1つのファイルに複数の PACKAGE を書く場合注意が必要かなと。
use strict;
use warnings;

package FOO;
my $hoge = "madoka";

package BAR;
my $moge = "homura";

package BAZ;
print "\$FOO::hoge : $FOO::hoge \n";
print "\$hoge      : $hoge \n";
print "\$BAR::moge : $BAR::moge \n";
print "\$moge      : $moge \n";

------------------
実行結果
$FOO::hoge :        # エラー
$hoge      : madoka # 期待と違ってエラーじゃない
$BAR::moge :        # エラー
$moge      : homura # 期待と違ってエラーじゃない

Name "BAR::moge" used only once: possible typo at - line 12.
Name "FOO::hoge" used only once: possible typo at - line 10.
この場合 $hoge も $moge もレキシカル変数なので
外から見えないことを期待しましたが、なぜか見えます。

では、次の場合はどうでしょう?
use strict;
use warnings;

package FOO;
my $hoge = "madoka";

package BAR;
my $moge = "homura";

package BAZ;
my $hoge = "mami";
my $moge = "sayaka";

------------------
実行結果
"my" variable $hoge masks earlier declaration in same scope at - line 11.
"my" variable $moge masks earlier declaration in same scope at - line 12.
「$hoge も $moge も同じスコープで既に使われてるよ」と怒られます。
PACKAGE が違ってもレキシカル変数は同じスコープみたいです。

これはこれで不便なので期待通りに動かすには次のようにします。
package FOO;
{
    my $hoge = "madoka";
}
もしくは
{
    package FOO;
    my $hoge = "madoka";
}
このように明示的にブロックで囲みます。
これを踏まえて書き直すと
use strict;
use warnings;

package FOO;
{
    my $hoge = "madoka";
    print "\$hoge : $hoge \n\n";
}
package BAR;
{
    my $moge = "homura";
    print "\$moge : $moge \n\n";
}
package BAZ;
{
    my $hoge = "mami";
    my $moge = "sayaka";

    print "\$hoge : $hoge \n";
    print "\$moge : $moge \n";
}

------------------
実行結果
$hoge : madoka 

$moge : homura 

$hoge : mami 
$moge : sayaka 
めでたし、めでたし。


- 追記 -
perlのドキュメントに書いてありました。
perlmod - Perl のモジュール (パッケージとシンボルテーブル) 【perldoc.jp】

パッケージ文は(local() を使った)動的変数にのみ効果を持ちますが、
my() によって生成されたレキシカル変数には影響しません。