CASIO腕時計購入(MTP-1228DJ-2AJF)

26年くらい使っていたSEIKO SPIRITS(7N48-7000)が動かなくなりました。
電池交換に出したのですが、どうも本格的に故障しているようで、修理にはそれなりの金額がかかる模様。新品価格が2万円ほどのはずで、修理に1万円以上かかるのもどうなんだろう、といったところです。

悩んだ末に、CASIOのMTP-1228DJ-2AJFという時計をビックカメラで購入。税込で2980円ほど。似た時計にMTP-1239DJ-2AJFというのもあって、こちらは二千円を切るのですが、販売終了の模様で入手できません。また、MTP-1228DJ-2AJFは10年電池ということで、その言葉通りならば、2年で切れてしまうMTP-1239DJ-2AJFよりも最終的に安くつくはず。コスパは非常に高い。

MTP-1239DJ-2AJFとの違いを書いておきます。
1239は針がとがった形であり、文字盤の大きさが大きく、ケースの素材が真鍮(1228はステンレス)といったところです。真鍮ということはメッキ加工がされているでしょうから、剥げてしまう可能性はありそうです。1228は少々重いのが欠点かも。
電池寿命も併せて、MTP-1228DJ-2AJFの方が高級ということにはなります。(レベルの低い争いではありますが、チープカシオの中では、上位の位置付けということになります。)


https://www.biccamera.com/bc/item/2041766/?source=googleps&utm_content=001260005005

ネット通販だと、ベルト調整が面倒そうだったので、ビックカメラの店舗に行って、そのままやってもらうことに。
2980円ですが、ビックポイント10%もつきますし、nanaco購入で0.5%ポイント、nanacoチャージで1.2%のポイントと考えると、350円弱のポイントがついているはず。

さすがに10万円の時計には見えないものの、1万円や2万円の時計と(ちょっと見た目には)変わらないようですし、やはりCASIO。満足がいくお値段かも。
難をいえば、少し重いということがありそう。あとは、青い文字盤は、角度によっては時刻確認がしづらいとか。

こんな書き方もできるんだ

今日、後輩のPerlコードをレビューしていたのですが、おや、と思うような書き方を見つけました。

package Foo;

sub hoge {
    my ($self, $bar) = @_;

    baz->($self, $bar);  # こんな書き方できるの?    
}

sub baz {
    my ($self, $bar) = @_;
}

$self->baz($bar) とかくのが普通だと思いますし、baz($self, $bar) というのも、まあ使えることは理解できます。
baz->($self, $bar) って何だろう…。普通に動いていましたが。

(\&baz)->($self, $bar);

と書かれれば、これもまた、動き自体は理解できます。

"baz"->($self, $bar);

あるいは、上記のように、文字列を書いてくれれば、確かにPerlのメソッドってコードリファレンスじゃなくて文字列でも動くよなと思いながら、納得します。

でも、barewordだと、「お!」と驚いてしまった。
奥が深いのか、あるいは私が無知なのか。

そんなことを思いながら、老害として「こんな書き方をするんじゃない」という訂正指示を出しました。

写真を美人化するブックマークレット

お手軽な美人フィルタ

私の勤める会社で今度ちょっとした発表をするのですが、久々にHTMLを題材にすることにしました。

昔から美人フィルタとかそういったものがありましたが、これをサーバや専用ソフトなしでHTML5canvasJavaScriptを使って実現しようという話。さらにカンタンに誰でも使えるようにブックマークレットにしてしまいます。お手軽ですね!

不細工化
オリジナル画像
美人化

Loading...

画像はモデルピースさんで配布されているフリー素材です。藤浦真菜さんという方の写真をトリミング、サイズ縮小させていただいています。

そして本題のブックマークレット

ブックマークレットは以下の通りです。なお、FirefoxChromeSafari(全てWindowsで最新版)では動くのを確認しました。AndroidでもOK(マウスでなぞるのはできませんが。)。

javascript:(function(){var%20FACTOR=0.8;function%20filter(org_img){var%20canvas=document.createElement('canvas');var%20context=canvas.getContext('2d');var%20_canvasW=org_img.naturalWidth;var%20_canvasH=org_img.naturalHeight;canvas.width=_canvasW;canvas.height=_canvasH;var%20imgObj=new%20Image(_canvasW,_canvasH);imgObj.src=org_img.src;context.drawImage(imgObj,0,0);var%20newImage=new%20Array(_canvasW*_canvasH*3);for(var%20y=0;y%20<%20_canvasH-1;y++){for(var%20x=0;x%20<%20_canvasW-1;x++){var%20pixelData1=getPixel(canvas,x,y,_canvasW,_canvasH);var%20pixelData2=getPixel(canvas,x+1,y,_canvasW,_canvasH);var%20pixelData3=getPixel(canvas,x,y+1,_canvasW,_canvasH);%20R=Math.abs(pixelData1.R%20-%20pixelData2.R)%20+%20Math.abs(pixelData1.R%20-%20pixelData3.R);var%20G=Math.abs(pixelData1.G%20-%20pixelData2.G)%20+%20Math.abs(pixelData1.G%20-%20pixelData3.G);var%20B=Math.abs(pixelData1.B%20-%20pixelData2.B)%20+%20Math.abs(pixelData1.B%20-%20pixelData3.B);setPixel(canvas,x,y,pixelData1.R-FACTOR*R,pixelData1.G-FACTOR*G,pixelData1.B-FACTOR*B,255,_canvasW,_canvasH);}}if(org_img.parentNode){org_img.parentNode.replaceChild(canvas,org_img);}else{org_img.appendChild(canvas);alert('not_replace');}}function%20getPixel(srcCanvas,x,y,canvasW,canvasH){var%20imagePixelData=srcCanvas.getContext('2d').getImageData(x,y,1,1).data;var%20R=imagePixelData[0];var%20G=imagePixelData[1];var%20B=imagePixelData[2];return%20{R:R,G:G,B:B};}function%20setPixel(srcCanvas,x,y,R,G,B,A,canvasW,canvasH){var%20context=srcCanvas.getContext('2d');var%20pixelImage=context.createImageData(1,1);pixelImage.data[0]=R;pixelImage.data[1]=G;pixelImage.data[2]=B;pixelImage.data[3]=A;context.putImageData(pixelImage,x,y);}var%20imgs=document.getElementsByTagName('img');for(var%20i%20in%20imgs){if(imgs[i].src==null){continue;}imgs[i].addEventListener('mouseover',function(ev){filter(ev.target)},false);}})();

長いですね。読む気にならないので解説もなしにしましょう。

使い方

使い方は、外部サイト http://atzy.info/bookmarklet.htmlにも書いておきましたが、簡単です。

ブックマークレットを保存したら、変換したい画像のあるページに行ってブックマークレットを選択します。
そして「えい!」と声をかけながら魔法をかける要領で画像をなぞります*1。そして数秒(画像サイズやPCのパワーによります)待ちますと画像が美人化します。

ただ、たとえばはてなのように、画像とページが同じドメインにない場合にはこの魔法がうまくかかりません。大人の言葉でいうとセキュリティに引っかかってしまいます。
しかし、その場合は、画像を右クリックで選択して、画像のみを表示したうえでブックマークレットを実行すればよいのです。

その他

  • 変換後画像は保存も可能
  • 画像が小さすぎると、けばけばしくなります
  • 画像が大きすぎると、あまり変わり映えしません
  • さて、こんなのが発表内容でいいのだろうか?

*1:ほんとはマウスなしで自動でやってもいいんですが、このマウスの「えい!」が少し気持ちいいのです。

そろそろPerl4に関して一言いっとくか(クラシカルPerl入門)

仕事でPerlを使うことになり、先週から久々に(本格的に)使ってみました。大体プログラミング言語なんてものは特殊なやつを除けばどれも根本は同じなので、それ自体で詰まるということはありません。
が、10数年ぶりのPerlを使いながら、懐かしいことを思い出してみました。思えば遠くへ来たものだ。

アンパサンド

Perl5以降では当然のようにサブルーチンを hoge() と呼び出しますが、Perl4では &hoge と呼び出します。

my!our!

Perl4では、my*1だとかありませんし、our*2ももちろんありません。
当然ながら、localを使います。

myはまさにレキシカルスコープ、ourはパッケージローカルな変数となります。で、Perl4に存在した(というか、今も存在しますが)localというのは、特殊なグローバル変数。その時点でグローバル変数の値を置き換えてしまい、ブロックを出た後でグローバル変数の値を戻します。つまり、以下では、test2()の中で$aが10ではなく1なのですね。myによる宣言とは意味が異なります。

$a = 10;

sub test {
   local $a = 1;
   test2();
}
sub test2 {
   print $a; # 10 or 1?
}

なお、localを使う意味はほぼ既にありません。

型グロブ

Perlにはグロブというものが二種類あり、一つがファイル名グロブ*3で、もう一つが型グロブです。

型グロブというのは、普通に生きている我々は使わないのですが、特殊な用途で利用します。Perlで使う変数やサブルーチンなどは総称して「シンボル」と呼ばれますが、この「シンボル」を統合して使うのが型グロブです。
何を言っているのかわからないかもしれませんが、簡単に言えば、$a、@a、%a、&aといったものを統合して*aとして指す機能が型グロブです。

それで何ができるのかといえば大したことができるわけではないのですが、Perl4ではたまに用途がありました。その一つが「ファイルハンドルの変数化」です。

ファイルハンドルは、何も考えずに使うとグローバルとなります。

open(FILE, "file.txt");
# このFILEはプログラム全体で参照可能。

これが非常にうざいわけです。例えばローカル化したり、サブルーチンの引数に渡したりしたいわけです。
しかし、このFILEは変数ではありません。

しかし、型グロブ*FILEを使うと、このFILEというファイルハンドルを変数のように使うことができます。

local *FILE; # FILEを局所化
open(FILE, "file.txt");

sub test{
   local(*FILE) = shift; # 変数のように使える。
   while(<FILE>){
      print;
   }
}

なお、仮に$FILEとか@FILEといったものが別個に存在した場合、*FILEによって巻き添えにされますのでご注意。

今なら、ファイルハンドルはモジュール経由で扱うことができます。

フォーマット文

Perl4でどうのという話ではありませんが、昨今のPerlであまり見かけない機能。確か昔は「はじめてのPerl」でも紹介されていた機能です。

$name = "Yamada";
$age = 30;
write REPORT;

format REPORT
|@<<<<<<<<< | @>>|
$name, $age
.

これによって、上で言えば$nameと$ageの内容を|Yamada | 30| のように整形して出力することができます。

なぜ使われないかといえば、formatで参照される変数は、グローバルである必要があるため。(ourやらlocalならば可ですが、myだとダメですね。)なお、formlineって機能がありますが、これも使われているのを見たことないですね。

dbmopen

最近は、ファイルDB(BarkleyDBなど)を直接に扱うことも少ないのかもしれません。が、tie*4を使って、DBとハッシュを結びつけるという手法があります。

ですが、Perl4ではdbmopen()を使います。はじめてのPerlでも使ってましたね。

dbmopen(%MYDB,'dir/dbfile',0666);

こうやって、DBに結びつけたハッシュを使います。ちなみに、閉じるときはdbmclose()があります。

今では使う意味がありません。

シンボリックリファレンス

リファレンスを使うのはPerl5では当然。しかしPerl4にはそのようなしゃれたものはありませんでした。

しかし、こんなことはできます。

$a = "abc";
$abc = "xyz";
print ${$a}; # これが print $abc; として働く

これがシンボリックリファレンス、あるいはソフトリファレンスです。皆様がPerl5で使っているものがハードリファレンス。
既に、使う意味は全くないといえるでしょう。use strict;すると使えませんし。

ハードリファレンスがないということは、矢印演算子もありません。

chop

chomp() によって、行末改行文字を切り取るのはよく使う機能の一つですが、これもPerl5から。Perl4ではchop()を使って、行末の1文字を切り取ります。

map

Perl4にはmap関数もありませんでした…。ですので、配列の置き換えはforeachなどを使っていました。

モジュール

そもそもモジュール自体ありませんでした。ですので、useすることもありません。requireによって他のコードを取り込むことはできました。

CPANからモジュールを引っ張ってきて簡単に機能が増やせるようになったのもPerl5のおかげ。

論理演算子

「かつ」や「または」といったものに、and/or/notを使えるのもPerl5から。Perl4では&&と||と!です。
とはいえ、Perl5でPerl4風の書き方が使われなくなったわけではありません。andと&&は結合の強さが違うので注意(他も同様)。

その他

パッケージ

パッケージはPerl4でもある、のですが、区切り文字は皆様の大好きな「::」ではなく、驚きの「'」(シングルクォート)です。

jcode.pl では &jcode'convert(*line, "euc"); なんて感じで文字コード変換を書いていました*5

プロトタイプ宣言

Perl4ではプロトタイプ宣言もできないわけですが、といって、プロトタイプ宣言ってそんなに使われてないような気もします。

連想配列

そういえば、Perl4では、ハッシュのことを連想配列(associated array)と呼んでいました。まあ、これは呼び名の問題に過ぎません。

正規表現

Perl4には最短マッチも先読みもありません。
その他、機能が大きく拡張されました。

配列の添え字

配列の添え字が負の数のときに後ろから数えてくれるとか?

不毛な争いはなかった

この手の言語は基本的にPerlしかありませんでした。
ですので、「PHP(笑)」とか「そろそろPHPに関して一言いっとくか」とか「ruby >>>>(超えられない壁)>>>> perl」とか「Perl(笑)は過去の言語」なんてことを言っちゃう人はいませんでした。

*1:Perl5で導入。

*2:Perl5.6で導入。

*3:Perl5ではglob関数がありますが、Perl4では普通は<*.txt>のように書いていましたな。

*4:Perl5で登場

*5:ここでも型グロブ! これで$lineを書き換えてもらいます。

repcachedのmemcached 1.4対応

mdounin(Maxim Dounin)さんが開発しているmemcached、あるいはrepcachedのforkがあるのですが、そこではrepcachedがmemcached 1.4.5に対応しています。

https://github.com/mdounin/memcached/tree/repcached

KLabで開発されていたrepcached(2.2まであります)は、memcached 1.2.8までの対応ですので、モダンなmemcached 1.4系を使うことができなかったわけですが、このmdounin版を使えばレプリ機能を使いつつ、memcached 1.4を使うことができるわけです。(ただ、おそらくマルチスレッドは無効化される。)

mdounin版の最新のものはrepcached 2.3と称していますが、あくまでブランチコードと思われます。なお、この最新版は、repcachedの問題であるところの「CPU使用率100%問題」の修正も入っています。

https://github.com/mdounin/memcached/commit/90ae0dfb122d4a13e3350eb6efd315f431e96772

これを見ると、一時的なネットワーク問題が起きた際の挙動が怪しいのを修正したとか何とか。
テストコードを見ると、以下のようなことをやっています。

  1. ノードBのみ一時停止(suspend)
  2. ノードAに大量更新
  3. ノードAを一時停止・ノードBを再開
  4. ノードBに大量更新
  5. ノードAを再開
  6. 1秒sleep
  7. ノードAからget、ノードBからget

ちょっと試した感じでは、レプリ先プロセスを止めて(ポートは開いたまま)大量の更新を走らせると、CPU使用率が100%になるような…。これが起きなくなるようです。

mixi API for PC

眠れなかったので、mixiアプリの作り方を読んでみた。
実際、そんなに難しくないですね。
儲けるのは難しそうですが、ちょっとしたものを作るくらいなら敷居は低そう。

プログラムはほとんどJavaScriptで書けばいいのかな。通信するサーバを作るならば、そこは好きな言語で書けばいいけど、それをするとサーバ管理も面倒だな。データ永続化機能もあるようだから、そっちに全部入れてJavaScriptだけで突っ走るのもありだね。

memcached

mixiでの大規模障害で少々恐れをなしていたmemcachedですが、私が使っている分にはまったく問題はないと判断して、安心していました。

が、最近別の問題でmemcached(repcached)について悩んでいます。いや、別にmemcachedに問題があるとかそういうわけではないと思いますが、それをどう使うかという方です。