nDiki : ソースコード

ソースコード - source code

2011年5月25日 (水)

なぜ Perl で配列に対して defined を使ってはいけないのか?

defined の挙動で相談されたのでソースコードを見てみたら、配列に対して defined を呼んでいた。 最近の Perl では配列に対して defined を使うのは非推奨である(perldata や perlfunc 参照)。 ほとんどの人が望むような判定結果は返ってこない*1

perl -e '@a = (); print defined @a ? 1 : 0; push @a, 1; print defined @a ? 1 : 0; shift @a; print defined @a ? 1 : 0'

配列が空かどうかならスカラーコンテキストで評価するだけで OK なのだが、Perl プログラミング経験上、1度は defined を使用してしまうだろう。 ただ通常は警告が出るのですぐ気がつく。 この警告は Perl 5.6.0 以降で出る。

 #!/usr/bin/perl

 use warnings;
 use strict;

 my @a = ();
 print defined @a ? "defined\n" : "undefined\n";
 push @a, 1;
 print defined @a ? "defined\n" : "undefined\n";
 shift @a;
 print defined @a ? "defined\n" : "undefined\n";

 # defined(@array) is deprecated at test.pl line 7.
 #         (Maybe you should just omit the defined()?)
 # defined(@array) is deprecated at test.pl line 9.
 #         (Maybe you should just omit the defined()?)
 # defined(@array) is deprecated at test.pl line 11.
 #          (Maybe you should just omit the defined()?)
 # undefined
 # defined
 # defined

しかしながら、配列への参照をデリファレンスしたものに defined を呼んでも警告を出してくれない。 相談ではまっていたのはこのケースだった。

 #!/usr/bin/perl

 use warnings;
 use strict;

 my $a = [];
 print defined @$a ? "defined\n" : "undefined\n";
 push @$a, 1;
 print defined @$a ? "defined\n" : "undefined\n";
 shift @$a;
 print defined @$a ? "defined\n" : "undefined\n";

 # undefined
 # defined
 # defined

なお配列(とハッシュ)に対する defined はメモリが割り当てられたかどうかを得るために使われていた。 Devel::Peek::Dump の結果を見てみると次のような感じ。 配列に要素を push した後に pop して空にしても、メモリは割り当てられた状態になるので defined が真を返すようになるのである。

 #!/usr/bin/perl

 use warnings;
 use strict;
 use Devel::Peek 'Dump';

 my @a = ();
 Dump(\@a);
 push @a, 1;
 Dump(\@a);
 shift @a;
 Dump(\@a);

 # SV = IV(0x9a6d064) at 0x9a6d068
 #   REFCNT = 1
 #   FLAGS = (TEMP,ROK)
 #   RV = 0x9a7dcd8
 #   SV = PVAV(0x9a6e0a8) at 0x9a7dcd8
 #     REFCNT = 2
 #     FLAGS = (PADMY)
 #     ARRAY = 0x0
 #     FILL = -1
 #     MAX = -1
 #     ARYLEN = 0x0
 #     FLAGS = (REAL)
 # SV = IV(0x9a6d184) at 0x9a6d188
 #   REFCNT = 1
 #   FLAGS = (TEMP,ROK)
 #   RV = 0x9a7dcd8
 #   SV = PVAV(0x9a6e0a8) at 0x9a7dcd8
 #     REFCNT = 2
 #     FLAGS = (PADMY)
 #     ARRAY = 0x9a78a20
 #     FILL = 0
 #     MAX = 3
 #     ARYLEN = 0x0
 #     FLAGS = (REAL)
 #     Elt No. 0
 #     SV = IV(0x9a6d064) at 0x9a6d068
 #       REFCNT = 1
 #       FLAGS = (IOK,pIOK)
 #       IV = 1
 # SV = IV(0x9a6d064) at 0x9a6d068
 #   REFCNT = 1
 #   FLAGS = (TEMP,ROK)
 #   RV = 0x9a7dcd8
 #   SV = PVAV(0x9a6e0a8) at 0x9a7dcd8
 #     REFCNT = 2
 #     FLAGS = (PADMY)
 #     ARRAY = 0x9a78a24 (offset=1)
 #     ALLOC = 0x9a78a20
 #     FILL = -1
 #     MAX = 2
 #     ARYLEN = 0x0
 #     FLAGS = (REAL)

ちなみに Perl 5.14.0 の pp_hot.c を見ると以下のようになっている。 配列だと AvMAX が 0 以上になっていれば真になる(十分条件)。 上の例でも pop した後も MAX = 2 となっていることから、defined が真を返しているわけだ。

 PP(pp_defined)
 {
     dVAR; dSP;
     register SV* sv;
     bool defined;
     const int op_type = PL_op->op_type;
     const bool is_dor = (op_type == OP_DOR || op_type == OP_DORASSIGN);

     if (is_dor) {
         PERL_ASYNC_CHECK();
         sv = TOPs;
         if (!sv || !SvANY(sv)) {
             if (op_type == OP_DOR)
                 --SP;
             RETURNOP(cLOGOP->op_other);
         }
     }
     else {
         /* OP_DEFINED */
         sv = POPs;
         if (!sv || !SvANY(sv))
             RETPUSHNO;
     }

     defined = FALSE;
     switch (SvTYPE(sv)) {
     case SVt_PVAV:
         if (AvMAX(sv) >= 0 || SvGMAGICAL(sv) || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
             defined = TRUE;
         break;
     case SVt_PVHV:
         if (HvARRAY(sv) || SvGMAGICAL(sv) || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
             defined = TRUE;
         break;
     case SVt_PVCV:
         if (CvROOT(sv) || CvXSUB(sv))
             defined = TRUE;
         break;
     default:
         SvGETMAGIC(sv);
         if (SvOK(sv))
             defined = TRUE;
         break;
     }

     if (is_dor) {
         if(defined)
             RETURN;
         if(op_type == OP_DOR)
             --SP;
         RETURNOP(cLOGOP->op_other);
     }
     /* assuming OP_DEFINED */
     if(defined)
         RETPUSHYES;
     RETPUSHNO;
 }

結論としては、良い子のみなさんは配列やハッシュに defined を使わないでねということで。

*1以下 Perl 5.14.0 で確認。

スポンサード リンク
[ 5月25日全て ]

2011年6月14日 (火)

今日のさえずり: 1/f ゆらぎを導入すれば bot も心地よくなるかな

2011年06月13日

  • 09:47 @rtmjp iPad でのリストの並び順変えられるんですか? ぜひ手順を教えてください! (ちなみにリスト内のタスクの並び順じゃなくてリストの並び順です)。
  • 09:58 @rtmjp いえいえ、わざわざありがとうございます。リストの並び順変更ができるか、Web 版の並び順と同じになると嬉しいです。指定リストの非表示ができるともっと嬉しいです。
  • 11:14 週末と今朝で Remember The Milk ルーチンワーク見直した。これでスムーズ感が少し戻るはず。
  • 11:39 mixi 「足あと」機能改修。昨日の時点で総アクセス数 184352 だった。 #mixi
  • 11:45 先週末納税通知書が届いていたのでそれをもって、特別徴収のお願いしてきた。
  • 12:39 若鶏唐揚二段弁当 450円。 (@ ローソン渋谷東一丁目店) http://4sq.com/jUQIGi
  • 13:29 「先週の訪問者」きた。
  • 14:05 ちょうどいい機会なので次の説明会は iPadノート取ってみるよ。
  • 20:54 退勤。

2011年06月14日

  • 09:20 告白手当とかいいな。
  • 09:25 RT @s_harada: 人のコードは平気で糞だと言うくせに、プロダクトに関して糞だと言えない時点でやっぱり部署間の空気の違いを感じる。
  • 12:49 渋谷駅周辺で RODHIA 安く売ってるのどこだろ。
  • 12:51 キムカル丼 490円。 (@ 松屋 渋谷宮益坂店) http://4sq.com/kS7ZiQ
  • 12:53 1/f ゆらぎを導入すれば bot も心地よくなるかな。
  • 13:20 ヒグチで FRISK 165円。この辺りで底値か。
  • 17:12 iPad 2 の書類出した。
  • 17:13 1フロア上のコーヒーの方が若干濃い。若干ね。
  • 17:56 iPad 場所を変えて何か検討するときにいいね。タイピングもまあまあいける。親指2本で。
  • 21:27 意思決定会議が不足している。
  • 21:49 退勤。
  • 22:03 ソースコードのフォーマットは基本的には郷に従え(ただし死んだバッチャンの遺言によるところは除く)。
[ 6月14日全て ]

2013年8月7日 (水)

プログラミング言語仕様・振る舞いを確認するために小さいプログラムを書く

プログラミング言語仕様・振る舞いを確認するために小さいプログラムを書く。 「この式を評価すると値は何になるの?」とか「この2つの書き方どっちが速いの?」とか「この正規表現にどうパターンマッチングするの?」とかを確認したい時。

当たり前の進め方だと思っていたんだけれど、そうすることを勧めたらスルー気味だったので。

特にスクリプト言語なら 「a.ほげほげ 」(Perl なら a.pl)なファイル作って実行してみればいいじゃんと思うのだけれど手間に感じるのかな。本丸のプログラムのソースコードを書き換えて試す(Apache 再起動して Web ブラウザでアクセスしてデバッグプリント読むとか)よりよっぽどはやいよ。あと、単体テストファイルでやっちゃうのもアリ。

それに適当に記事としてまとめておけば、今度は自分が他人に説明する時にそれを示せば済むようになるしね。

[ 8月7日全て ]

2013年10月2日 (水)

Emacs の ffap-perl-module.el でカーソル位置にある Perl パッケージ名のファイルを開く

VimPerl ソースコード上でパッケージ名の上にカーソルがあるときに gf するとそのファイルを開くんだけど、……」という話が出て、あ、それ Emacs でもやりたいと思って調べて設定した。

最初は FFAP の設定。実は今まで知らなかったのだけれど ファイル名などをポイントしている時に Cx C-f するとそのファイル名を guess してくれるl FFAP というのが標準で入ってた。

 (ffap-bindings)

で有効になる。

これでファイル名は OK。Perlパッケージ名からファイル名を guess してもらうには ffap-perl-module.el を使う。

上記から ffap-perl-module.el を取ってきて load-path の通っているところに置く。で以下を設定に追加。

 (eval-after-load "ffap" '(require 'ffap-perl-module))

これで Perl ソースコード中のパッケージ名が書かれているところにカーソルがある時に C-x C-f するとそのモジュールファイル名を minibuffer にデフォルトで出してくれるようになる。捗る。

なおデフォルトだと system Perl の @INC にあるものを探しにいくようになっているので、perlbrew 下だったり Carton で入れた local/ 下だったり開発中のモジュールだったりを見つけられるようにするには ffap-perl-module-path を設定しておく必要がある。

 (setq ffap-perl-module-path
       '("/path1/to/lib"
         "/path2/to/lib"))
[ 10月2日全て ]

2013年10月19日 (土)

ITエンジニア逆求人フェスティバルではソースコードを見たい

両国の KFC Hall で開催された、株式会社ジースタイラス運営の2015年卒対象「ITエンジニア逆求人フェスティバル」という企業・学生交流イベントに参加してきた。この手のは5月のサポーターズ主催イベント以来。

5月の時はまだ夏前でインターンシップが目下の感心事といった感じだけれど、今の時期になると就職活動という意味合いが強い感じ。

「ITエンジニア」というくくりなので必ずしも Web 系志望じゃない方がいるのはあるとして、それ以前にエンジニア志望じゃない人も参加されていたのは運営に課題があるんじゃないかな。あと経験されている技術要素して Unity・OpenCV・Kinect などを上げている方が多かったかな。なにか恣意的な参加者人選なのだろうか。

特に Web 系は独学である程度やってみる・作ってみるという事ができる高速道路が敷かれている世界なので、学生時代からいろいろされている人も多い。やっている、やっていないで結構差が出るので、Web 系を目指しているけれども何もやっていないという方はすぐにでも何か始めると良いと思う。

もちろん選ばれる立場として、優秀な方々にそこで活躍したいと思われる企業にならなければと身を引き締めなおした1日でもあった。

以下所属組織とは関係ない個人的見解:

  • プレゼンテーション用のノート PC にはソースコードを入れておいて、見せてもらえるようになっていると嬉しい。ざっと拝見したい。デモよりもソースコードPowerPoint よりもソースコード
    • GitHub にありますというのはナイスだが、ネットワーク環境によってはぱっと見られない可能性があるのでローカルに clone してある状態になっていて欲しい。
  • エントリーシートの「授業でやりました的プログラミング言語列挙」はナンセンスなので無いと嬉しいし、運営もそのように誘導して欲しい(がっつり何かを作ったというのならアリだけれど)。
  • ソフトウェアとあまり関係のないサークル活動の紹介とか(相当のリーダーシップの資質が感じられない限り)ほとんどスルーなのであまりアピールしなくても平気。

でも自分が学生の頃そんなの全然出来てなかった……。

[ 10月19日全て ]

2013年11月15日 (金)

GitHub トレーニングチームから学ぶ Git の内部構造 #githubjp に行ってきた

naney:10867844766

GitHub 主催の「GitHub トレーニングチームから学ぶ Git の内部構造」に行ってきた。会場は Yahoo! JAPAN のある東京ミッドタウン。

内容的には「入門Git」の始めの方で説明されている Git のデータ構造(もはやファイルシステム)について。「Git の内部: グラフ、ハッシュ、圧縮」というのがトピックとのことだったので、漠然と Gitソースコードレベルでの話題になるのかなと思っていたのだけれど、そうでなかった。

新しく知った事:

  • ./git/objects/<..>/<filename> の<..> の2文字はオブジェクト ID の最初の2文字(大量ファイルのディレクトリ分割のためというのはわかっていたけれど、ああ単純に最初の2文字だったんだ)。
  • git fsck でリポジトリの不整合が見つかっても復旧はできない。復旧バックアップからすること。
  • pack という処理がある。詳しくは後で調べる。

オブジェクトが不変でかつ同じ内容ならオブジェクト ID が必ず同一になることを利用して、オブジェクトファイルを共用していることを発表中「ハードリンク」と言ってしまったけれど、多くの人がファイルシステムのハードリンクで実現されていることと勘違いしていた模様。質問を受けて説明しなおしていたけど。

ちなみに実際にファイルシステム上でハードリンクになるのは、ローカルリポジトリを指定して clone した時。大きなリポジトリでもローカル内で clone する分にはストレージ容量的にはあまり気にしなくて大丈夫。

[ 11月15日全て ]

2013年12月4日 (水)

Git の contrib/diff-highlight で文字列レベルの差分ハイライトと lv (未解決)

Git の contrib/diff-highlight を使って行単位ではなく文字列単位で異なる部分をハイライトしてくれるという記事を教えてもらった。

自分の設定では .gitconfig の color のところは

 [color]
         branch = auto
         diff = auto
         grep = auto
         interactive = auto
         showbranch = auto
         status = auto

となっていて pager 指定は .bashrc で

 if command -v lv > /dev/null; then
   export GIT_PAGER='lv -Ou8 -c'
 fi

と今している。diff-highlight*1 を PATH の通っているところにおいて、

 GIT_PAGER='diff-highlight | less -R' git diff HEAD~..HEAD

とかすると文字列単位で差分が反転色で表示される。

lv だと \x1b[7m で反転させるとそれまでの色属性が落とされてしまうのか、行のそれ以降が黒白/白黒になってしまう。 lv v.4.21*2ソースコードを軽くみたけどちょっとしっかり読まないと対応できなさそうなので、今日は諦め。

diff-highlight は Perl スクリプトなので、こちらでハイライト開始とハイライト終了時のエスケープシーケンスをいじって lv で見栄え良くなるようにするのが簡単でいいかもなあ。

*1Debian GNU/Linux だと /usr/share/doc/git/contrib/diff-highlight/diff-highlight にある

*2(Debian GNU/Linux だと v.4.51.a が入っているので、見たのはちょっと古いバージョンだった模様)

2014年02月05日追記

nkf を通す方法を教えてもらった

[ 12月4日全て ]

2014年2月5日 (水)

Vim の jellybeans カラースキーマに似た Emacs テーマ Ujelly

image:/nDiki/2014/02/05/Ujelly-2014-02-05-shadow.png

Vim の jellybeans カラースキームにインスパイアされて作られたという Emacs 24 のカスタムテーマ Ujelly を入れてみた。

custom-theme-directory を設定するほどでもないので、require できるところに ujelly-theme.pl を配置しておいて、

 (if window-system
     (when (>= emacs-major-version 24)
       (when (require 'ujelly-theme)
         (load-theme 'ujelly t))))

としてロードするようにした(ujelly-theme.el を読むとその中で自身のあるディレクトリを custom-theme-load-path に追加してくれる)。

今までは Solarized の dark を使っていたんだけれど、ディスプレイが暗い時(省電力のためノート PC液晶モニタを暗くしている時)に見づらいなと思っていたのでもうちょっとハッキリした感じのにしようかなと。

Ujelly テーマでソースコードを開いてみたら、くっきりメリハリがあって見やすくテンションが上がった。いい感じ! (スクリーンキャプチャPerl 5.18.1 の Data::Dumper のソースコードの一部)。

ただ実際に入れてみると Solarized は目に優しいなとあらためて実感して良さを再認識することにもなった。Solarized も捨て難いね。

[ 2月5日全て ]

2014年2月20日 (木)

今日のさえずり: C-t o してしまってソースコードが気がつくと壊れていて悲しい

2014年02月20日

[ 2月20日全て ]

2017年5月29日 (月)

ホテル三日月はいい値段とか【日記】

夏に竜宮城スパホテル三日月で2泊ぐらいどうかなーという話があったのでちょっと調べたのですが、7月下旬とかだと1泊2万円超なんですね。結構しますな。

それから、アプリ開発のチームにも入ることになったので iOS アプリの開発環境を用意した方が良いかなと思ったのですが「コードは書く予定ないですよね? であれば Xcode でソースコードが見られるぐらいでどうですか」となりました。確かに書く余裕は無いですね。

仕事で使っている15インチ MacBook Pro はまだ OS X El Capitan のままなので Xcode を入れるにはまずはそこのアップデートが必要。そこからか。

[ 5月29日全て ]

About Me

Naney Naney (なにい)です。株式会社ミクシィでマネージャー・プロダクトオーナーをしています。

nDiki1999年1月に始めたコンピュータ日誌を前身とする NaneyWeb 日記(兼パーソナルナレッジベース)です。ちょっとしたノートは nNote にあります。

follow us in feedly

※内容は個人的見解であり所属組織とは関係ありません。

月別インデックス
Process Time: 0.930042s / load averages: 0.74, 0.61, 0.53
nDiki by WATANABE Yoshimasa (Naney, Google profile)
Powered by DiKicker