sironekotoroの日記

Perl で楽をしたい

Macbook Airの環境整備 20160921

管理者権限が必要な AppleScript アプリをパスワード入力無しで動かす

AutoChargeInHabit

バッテリー制御ソフト - AutoInflowDisable

  • 実際に効果があるのかどうかは、比較対象となる MacBook Air が無いので不明
  • 分からないのだけど、「鰯の頭も信心から」的に使わせてもらっております

    • 信仰にはお布施が必要なんでちゃんと 1000円くらい donate したぜ
  • 時々バッテリの状態をメモってた

    • この Mac について -> 詳しい情報 -> システムレポート -> 電源 の 完全充電時の容量(mAh
      • 2014-08-24:6724
      • 2014-09-17:6967
      • 2014-10-12:6329
      • 2015-01-28:5665
      • 2015-05-24:6170
      • 2015-12-19:5934
      • 2016-01-17:5791
      • 2016-04-09:6178
      • 2016-09-19:5978
  • ちなみに、交換バッテリは 7150mAh らしい

  • MacBook Air 13" (Mid 2012 through Early 2015) Battery (661-7474) - iFixit

    Replacement 7150 mAh battery compatible

  • バッテリに神経質にはなっていないけど、長持ちするならその方がいいよねぇ、と思ってます

    • しかし、真に神経質でない人ならこのソフト入れないだろうから、ちょっとは神経質なのだろうか
  • なお、MacBook Air の充放電回数の上限は1000回との事

  • Mac ノートブックのバッテリーの充放電回数を確認する - Apple サポート
  • さっき自分の MacBook Air 確認したらちょうど500回だった

起動の都度のパスワード入力が鬱陶しい

  • このソフトを MacBook Air の起動時に立ち上がるようにしていたのだけど、都度管理者パスワードを聞かれるわけです

  • メンドイなぁ・・・と思いつつ、しかし解決法もわからずで2年間

  • 勉強の合間の気分転換で手を入れてみたところ、なんとかなったので備忘録もかね書いておきまする

    • なお、試行錯誤に3時間ほどかかった模様
  • 最初は、「自動でパスワードを入力しよう」と思い、 Automator などをいじってみたんですが、パスワードをテキストボックスに入力できず

  • 作者は 「 sudo で動かしている」との事ですが、当方では sudo で動かしてもパスワードを要求される

  • 結局、AppleScript で一部を書き換えることに

    • ところで、 AppleScript って情報めっちゃ少ない・・・うちのググラビリティが及ばない分野でした
  • 書き換えるのは権利者権限を要求する AutoChargeInhibit2RunRoot.app

  • これを AppleScript エディタで開き
  • オリジナル

    do shell script theAppPath & " &>/dev/null & " with administrator privileges

  • 変更後。******** の部分にMacの管理者パスワードを入れる

    do shell script theAppPath & " &>/dev/null & " password "********" with administrator privileges

  • これで管理者権限を求められる事がなくなりました

  • 起動、再起動の都度入力を求められていたパスワードを入れる事がなくなり、しかも自分でなんとかできたって事で、結構感動したのでした

追記

  • この記事を書きながら「時々バッテリの状態をメモってた」って何よ?と
  • プログラマの三大美徳を信条とするなら、これを自動化するべきではないだろうか?
    • まだまだ怠惰が足りない
# MacBattery.pl
# その時点のバッテリの再大容量ログを
# YYYY-MM-DD hh:mm:ss ????
# の形式でファイルに出力する

use 5.012;
use warnings;
use Time::Piece;
binmode STDOUT, ':encoding(UTF-8)';

my $command = 'ioreg -c AppleSmartBattery | grep MaxCapacity';
my $max_capacity = $1 if ( `$command` =~ /(\d+)/ );

my $t   = localtime(time);
my $date = $t->ymd .' '. $t->hms;

my $save_filename = 'Mac_MaxCapacity.txt';

open my $FH, '>>', "$save_filename"
    or die qq{Can't open file "$save_filename":$!};

say $FH $date , ' ' , $max_capacity;

undef $FH;
  • こいつを cron に登録して・・・え? MacOS X にcron ないの?
    • めんどくせぇ・・・ってなったが、真の怠惰目指して頑張る

Scheduling Timed Jobs
Note: Although it is still supported, cron is not a recommended solution. It has been deprecated in favor of launchd.

  • plist ファイルの書き方をググる
    • 起動時のみ設定
    • plistファイルに 755 の権限つけたけど、必要かどうか試してない・・・
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>pl.Mac_MaxCapacity.perl.plist</string>

    <key>ProgramArguments</key>
    <array>
      <string>perl</string>
      <string>/scriptdir/MacBattery.pl</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

  </dict>
</plist>
  • 起動時に .pl で指定されたファイルに出力された事を確認

すぐわかるオブジェクト指向Perl 2周目

オブジェクト指向Perlマスターコース」から一時撤収

  • 2016年8月
  • 分からないなりに読み進む、という選択肢はあるものの、どうにもやる気が出ずに眠くなる
  • 自作スクリプトを書いていて、「俺のオブジェクト指向Perlはこれで良いのだろうか?」という不安を放置している
  • なんでもクラス内のプロパティに格納するクセがついてしまった。あまり良い事ではなさそうなので矯正したい
  • というわけで、もう一度基礎に立ち返る事にする。
  • もひとつ。高名な・・・寿司LoverでCTOでゲーマーで技術顧問のnaoyaさんのこのツイートを見て決心したというのもある。

第1章

  • さらっと。
  • File::Find はホント素晴らしいよな・・・
    • サブルーチンを引数で渡す、っていう意味が今ならわかる。

第5章

上のプログラムで

$codeRef = \&daikeiNoMenseki(3,4,5);

の用にサブルーチンに引数を渡してしまい、コードレフの取得とサブルーチンの実行を一気に行おうとしては(?)いけません。
上のように書いた場合は、 &daikeiNoMenseki(3,4,5) によってサブルーチン実行がおこり、戻り値17.5という無名スカラーへのリファレンスが $codeRef に入りますが、そんなことしたい人は絶対にいないと思います。
138p

  • サブルーチンの実行と戻り値の取得が出来て楽でよさそう、とか思ったけど、なるほど。

第11章、というよりも「翔丸

  • 途中、クラスとインスタンスの説明で能條純一のコミック「翔丸」を取り上げて説明する部分があり、一度読んだときによく分からなかったんですね
  • 二回目を読むにあたり、原作全3巻を読んでみたんですが・・・主人公がカッターナイフをふるう都度(そんで仲間が増える都度)「インスタンス」「インスタンス」って思い浮かんできて別の意味で楽しかったです
  • でも原作読まないと分かんないよなぁ、これ
  • 翔丸 - Wikipedia
  • うちだったらどんなたとえを使うだろう・・・
    • 吸血鬼
      • クラスオブジェクト:吸血鬼、ヴァンパイアロード?
      • コンストラクタ:噛みつき
      • インスタンスクラス:血を吸われた人
      • メソッド:噛みつき、引っ掻く
    • ゾンビ
  • なかなかに難しい

第11章(翔丸抜き)

  • 自分である程度オブジェクト指向でプログラムを書いてみて、改めてこの本を読み返すと本当によく分かる。
  • そして、最初に読んだ時、いかに適当に読み飛ばしていたか・・・
  • まぁ、それでもそれなりに書けるんだから、この本すごい、Perlすごい
  • クラス、クラスオブジェクト、インスタンスオブジェクト、コンストラクタ、オブジェクト、プロパティ、メソッド、メッセージ、分かる!わたしにも分かるぞ!

第12章

  • プラグマモジュール、 overload の "0+" って何?って思ったけど、 Perl演算子の一つなんだ・・・
  • オブジェクトと数値や文字列を同時に引数にとる時、第一引数がオブジェクトになるよう、自動的に引数の順番が並べ替えられる。
  • 並べ替えが行われた場合には、第3引数に真値が入る
  • すごい、1周目やったときの記憶が無い・・・

第14章

  • Calendar::Simple を使った CGI
  • だけど2周目なので、ちょっと変えて軽量 WAF の Mojolicious::Lite を使って実装
#!/usr/bin/env perl
use Mojolicious::Lite;
use Calendar::Simple qw(calendar);
use Time::Piece;

# Documentation browser under "/perldoc"
plugin 'PODRenderer';



get '/' => sub {
    my $self = shift;

    my $t = localtime;
    my ($year,$month,$day) = split /-/ , $t->ymd;

    my $cal  = calendar($month , $year);
    $self->stash( cal => $cal ,year => $year , month => $month);
    $self->render('index');
};

post '/' => sub {
    my $self = shift;

    my $year  = $self->param('year');
    my $month = $self->param('month');
    my $cal   = calendar( $month, $year );
    $self->stash( cal => $cal ,year => $year , month => $month);
    $self->render('index');
};

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!


<form action ='<%= url_for %>' method='post'>
    <%= number_field 'year' , style => 'width:50px' %>年
    <%= select_field 'month' => [(1..12)] %>
    <input type='submit' value='表示'>
</form>

<table border=1>
    <tr>
            <th>日</th>
            <th>月</th>
            <th>火</th>
            <th>水</th>
            <th>木</th>
            <th>金</th>
            <th>土</th>
    </tr>
%    for my $week (@$cal){
    <tr>
%        for my $day (@$week){
            <td><%= $day %></td>
%        }
    </tr>
%    }

</table>

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body>
    <%= content %>
  </body>
</html>

2周目を終えて

  • 2016年9月19日
  • オブジェクト指向Perl マスターコース」を早々に挫折して戻ってきた本書だけど、うん、戻ってきてよかった
  • 1周読んだ時には無い発見があった
    • つまり見落とし
  • 用語を整理できて、改めてオブジェクト指向Perl の入り口にたてた気がする

オブジェクト指向Perlマスターコース 第3章 〜 第5章

「遅れてきたもの」の悲しみ

  • この「オブジェクト指向Perlマスターコース」は2001年の初版をつかっているのだけど、誤記?にぶつかった。
  • さてさて正誤表は、と思ったら出版社が無い
  • 正確には同じ名前の出版社はあるんだけど、もうプログラミング言語書籍の仕事してない
  • 正誤表無しは辛い・・・
  • けどまぁ、古代の古文書だって正誤表無いだろうし、分かる範囲でがんばってこう
  • そんで、「うちより後」にこの本を読む人のために気づいたところは書いておこう

    • でも、この本を手に取る位の人であればいらないんじゃ・・・とも思う
  • 今日見つけたのはこれ

  • 114p リスト3.1 クラスCD::Music
  • 誤、と思われる
    $self->{_room}  = $roomif $room;  
    $self->{_shelf} = $shelfif $shelf;
  • 文脈からいってこうだろうな
    $self->{_room}  = $room  if $room;  
    $self->{_shelf} = $shelf if $shelf;
  • 123p 118pの name から get_name への変更が反映されてないので直す
  • 128p use Carp 'croak' が必要
  • 129p AUTOLOAD から呼び出したチェック用サブルーチン _accessible がうまく動かず、常に偽を返す
    • サブルーチン accessble が参照するハッシュ %attrs を参照できていない模様
    • この本が出た 2001年頃の Perl では動いたのかなぁ
    • とりあえず、チェック用サブルーチンの中にハッシュを入れる事で動きはしたけど、カプセル化が出来ているかどうかは不安がある
{

    sub _accessible {
        my %_attrs = (
            _name      => undef,
            _artist    => undef,
            _publisher => undef,
            _ISBN      => undef,
            _tracks    => undef,
            _rating    => undef,
            _room      => undef,
            _shelf     => undef,
            _incr      => '1',
        );

        return exists $_attrs{ $_[1] };
    }

}

第4章、第5章

  • だんだん理解できないところが増えてくる
  • それでも一通りは読む
  • 所々、現在のPerlでは推奨されない仕組みについての解説があったりする
    • 例えば第4章で出てくる擬似ハッシュ
  • 第5章では、正規表現リファレンスをオブジェクトに格納して使い回す、というのがあった
  • 既存の機能(正規表現)を自分好みに作り替えていいんだ・・・という当たり前だけど、いままで気づけなかった感動があった
  • プログラミングは自由だなぁ

すぐわかる オブジェクト指向 Perl 第9章 オブジェクト指向モジュールの活用

ありがたい!

  • !!!
  • ありがとうございます作者さん、おかげで本を全部味わう事が出来る!
  • ってことで、飛ばしていた9章にチャレンジ
  • まずは、Calendarモジュールのインストールに再挑戦。
cpanm --install http://ftp.auckland.ac.nz/CPAN/modules/by-module/Calendar/YEWENBIN/Calendar-v0.4.2.tar.gz

「すぐわかる オブジェクト指向Perl」という本

  • そうそう、この本について、dankogai氏が書評を書いているのを発見

    • っても、2008年!8年も前だ。
  • 404 Blog Not Found:$this->get if $you->learn(slow) - 書評 - すぐわかるオブジェクト指向Perl

    リャマやアルパカは、私から見るとずいぶんとゆっくりなのだけど、それでも速すぎる生徒がいることを忘れてはならないのだ。しかし、本書なら大丈夫。カメでも学べます。

  • まさにこの言葉通り。ドジでのろまな亀の自分でも、とっかかりを掴むことができた
  • 一つの物事を体系的に学ぶとき、インターネットよりは本で一気通貫で学ぶのが、とても良いと再認識させられた
    • ついでにいうと、リャマ本(はじめてのPerl)、アルパカ本(続・はじめてのPerl)より面白かった
    • これも「わかる」って実感を与えながら微速前進してくれたからだと思う

今日の午後3時間くらい悩んでいた事

オブジェクト指向の勉強中・・・

クラスを作ったパッケージ内にある変数に、メソッドを経由してアクセスしたい

  • testClass クラス の中の access サブルーチンから、おなじパッケージ内の $str にアクセスしたい
  • 不精をして、1つのファイルで package で分けることでクラスを作ったりという事をしておりました(フラグ
# test.pl
use 5.012;
use warnings;
use utf8;
binmode STDOUT, ':encoding(UTF-8)';

# オブジェクト作成
my $object = testClass->new;

# オブジェクト経由でメソッド動かして、
# testClassの中の $str の値を表示させたい
print $object->access;


# ----- main パッケージここまで -----
package testClass;

# packageの中にはあるけど、メソッドの中には無い変数
my $str = 'testClass package';

# コンストラクタ
sub new {
    my $class = shift;
    my $name = {};
    bless $name , $class;
}

# このメソッドで同じ pakcage の中にある $str を返す
sub access {
    my $class = shift;
    return $str;
}
1;
  • が、エラー

    Use of uninitialized value in print at ...

  • $str にアクセスできない・・・なぜだ

  • このあと、use strict 外したり、 my の代わりに our とか local 使うなどするも解決せず。

解決

  • ちゃんとファイルを分けたら動いた
  • でも、なぜ1つのファイルで分けたらダメなのか理解できず
  • 不精はいかん、ってことだけど、うーん、なぜだ。分からん。
# test.pl
use 5.012;
use warnings;
use utf8;
use testClass;
binmode STDOUT, ':encoding(UTF-8)';

# オブジェクト作成
my $object = testClass->new;

# オブジェクト経由でメソッド動かして、
# testClassの中の $str の値を表示させたい
print $object->access;
# testClass.pm
package testClass;

# packageの中にはあるけど、メソッドの中には無い変数
my $str = 'testClass package';

# コンストラクタ
sub new {
    my $class = shift;
    my $name = {};
    bless $name , $class;
}

# このメソッドで同じ pakcage の中にある $str を返す
sub access {
    my $class = shift;
    return $str;
}
1;

しかし・・・

  • testClass.pm の $str を { } で囲むと動かなくなる・・・これではカプセル化が・・・ううむ

オブジェクト指向Perlマスターコース 第1〜2章

「遅れてきた自分」が感じる Perl の素晴らしさ

  • うちのように齢 30 超えてプログラムに興味を持った人にとっては、Perl はとても良い選択
  • なんせ、「枯れた言語」であるので、大昔の本でも今に生かせる知識がある
  • 他にも枯れた言語はあるけど、すぐに実行できて、分かりやすく、コミュニティ活動があり、未だに web の第一線で使われている、という Perl の有り難さがある

ということで「オブジェクト指向Perlマスターコース」

  • 先に学んでいた「すぐ分かるオブジェクト指向Perl」で参考書籍にあげられていた本
  • Amazon では新刊は入手できず、マーケットプレイスで入手
  • 「枯れた言語」だと参考書籍も安く上がってありがたい
    • でも、申し訳なさもある・・・著者の方には一銭も入らないわけだし
    • Perl 本の新刊はちゃんと買うようにしているんだけどね
  • 正直、!5年前(2001年)に出た本を買うのは勇気がいったが、ま、買わない事には無駄かどうかも分からない
  • 1つ得るものがあって、ずっと生かす事が出来れば、安い投資である

第1章 オブジェクト指向入門

概念 別名
オブジェクト クラスインスタンスインスタンス変数
クラス ユーザー定義型、オブジェクトテンプレート、メタオブジェクト、パッケージ、モジュール
オブジェクト属性 フィールド、スロット、インスタンス変数、メンバオブジェクト、データメンバ
クラス属性 クラス変数、クラスフィールド、インスタンス変数、メンバオブジェクト、データメンバ
オブジェクトメソッド インスタンスメソッド、セレクタ、ハンドラ、メッセージハンドラ、フィーチャ、メンバ関数、オペレーション、パッケージオペレーション
クラスメソッド 静的なメソッド、静的なメンバ関数、共有メソッド
メソッド呼び出し メソッド起動、メッセージ、イベント
インターフェイス プロトコル、機能集合
継承 サブクラス化、クラスの特殊化、導出
カプセル化 データ隠蔽、データプライバシー
総称クラス テンプレート、パラメータ化クラス、総称パッケージ、総称モジュール
多態的メソッド 仮想関数、総称メソッド、優先オペレーション、メソッド
抽象メソッド 純粋仮想関数、延期機能
スーパークラス 親クラス、基底クラス
サブクラス 子クラス、派生クラス
  • まぁ、正直言うとこの表みたときに感じたのは「殺意」
  • こんなに別名多いのかよ!
  • なるほど、Web から拾い読みしてただけでは用語が混ざって、一生オブジェクト指向わかんないなぁ
    • 今だったらもっと増えてそう

第2章 Perl入門

  • この辺りはさらっと
  • 今までの積み重ねが生きてる感
  • とはいえ、 wantarray はサブルーチンからの返り値チェックに積極的に使っていきたい
sub subroutin {
    return wantarray();
};

my $scalar = subroutin();
print $scalar , "\n"; # ""

my @array = subroutin();
print @array , "\n"; # 1

  • 型グロブの存在意義、今まで全く理解できなかったんだけど、以下の説明で腑に落ちるところがあった

しかし型グロブでは、さらにもう1つの重要なテクニックとして、選択的に割当を行う 事が出来る型グロブに様々な種類のリファレンスを割り当てた場合、対応する種類の型グロブのスロットのみが置換される。
perl *SOURCE = \$SOURCE1; *args = \@ARGV; *do_it = sub {print "coin' it!\n"}; つまり上記3つの割り当てで、$SOURCE$SOURCE1 の別名になるが、 @SOURCE , %SOURCE , &SOURCE などは影響を受けない。同様に、 @args@ARGV の別名になり、 &do_it は無名サブルーチンの別名になる。
(中略)
この割り当ての動作はポリモーフィズムの一例である。つまり、刺激(割り当て)は常に同じであるが、反応(型グロブで実際に変更される部分)は、割り当てられている値のデータ型に依存する。

最近のPerlの勉強とか:2016年06月

最近やっている事

  • 「すぐわかるオブジェクト指向Perl」を読み終えた後、既存の自作プログラムの改修をやっておりました
  • RSSフィードを持ってきて、自分の好きに変形して出力するもの
  • 以前に作ったものはこういうもの
    • 再利用性考えてないので、1つのRSSフィードに1つのスクリプトで対応
    • モジュールはネットに書いてあった例をコピペ、又はそれにして毛を生やした感
      • それでもちゃんと動くんだからたいしたもの
    • 機能ごとにサブルーチンに分割してある
      • 他のRSSを処理する時はサブルーチンをコピペ
      • しかし、作成時期により微妙な差異がある
    • VPS上の cron でうまく動かなかったので、 シェルスクリプトに起動スクリプトを書いて、そこから Perl スクリプトを呼ぶという謎仕様
  • これを以下のように変更
    • オブジェクト指向で作り直し
    • 共通した処理である、RSS取得 , パース , Atomへの変換 , 出力 をメソッドで実装
    • RSSフィードごとに異なる再構築部を個別で実装
    • プロパティの取得と変更はちゃんとセッター、ゲッター経由で実施
    • cron から直接スクリプトを呼んで実行させる
      • cron から plenv で入れた Perl にパスが通っていなかった事に気づき解決

作りなおしてみて

  • RSSフィードごとに異なる部分と共通処理部分を分離する、というのが実現できて嬉しい
    • さらに楽
  • オブジェクトの中のデータをメソッドでグニグニするという感覚を得る事が出来た
  • それは既に Time::Piece とか Web::Scraper で使わせてもらっていた事ではないか!という気づき

これからのPerl勉強

  • 他の既存プログラムの改修
  • さらなるPerlの勉強
    • 職場の昼休み中に結城先生の「Perlクイズ」を1日1問ずつ
    • 土日に集中して・・・何をやろうかねぇ。以下の本が候補なのだけど
  • あと、テストを書く習慣が無いので、身につけないとなぁ
    • いまは Data::Dumper 使って say Dumper $hogehoge 頼み
  • PerlTidi 頼みなので、ちゃんと Perl Best Practice 読む
  • それに、そろそろ仕事で本格的に楽をするためのプログラム組みたい・・・
  • 楽をして儲かるとなお良い・・・
  • やりたい事いっぱいだ!

そういえば

  • 昔を思い出す
    • オブジェクト指向?知らなくても動くプログラム作れるよ」
    • 「リファレンス?知らなくても動くプログラム作れるよ」
    • 「ハッシュ?知らなくても(略」
  • そんなふうに考えていた時期が俺にもありました
  • 構造や働きをまとめることで結果、楽をする事が出来るって素晴らしい事なんだよなぁ
  • きっともっと楽をしたり、出来る事が広がる知識があるはず
  • なにより、「俺の考えた最強のプログラム」作って動かすのはとても楽しい!

One More Thing

  • Javascript も勉強してたけど、自作Perlスクリプトを作り直すのが楽しくて手を付けてなかったので再開させる