2009-06-23

ターミナルにダイアログを表示するコマンド whiptail

Linux でターミナルにダイアログを表示するコマンド whiptail を発見した.

$ whiptail --msgbox hello 25 80

とか.

2009-06-17

Objective-C のメソッドは virtual か?

Objective-C のメソッドは C++ でいうところの virtual なのだろうか?

#include <stdio.h>
#import <objc/Object.h>

@interface B : Object
- (void)speak;
@end

@implementation B
- (void)speak
{
    printf("speak B\n");
}
@end

@interface D : B
- (void)speak;
@end

@implementation D
- (void)speak
{
    printf("speak D\n");
}
@end

int
main()
{
    B *b = [[D alloc] init];
    [b speak];
    return 0;
}

をコンパイル,実行すると speak D と表示されるので,答えは "Yes" である.

このサンプルコードを書く時にうまくいかなかったこと

alloc の呼び出しが undefined になる.

これは以下のように解決できる.

  • B を Object から派生させる.そのためには #import <objc/Object.h> が必要になる.
  • -lobjc で objc ライブラリをリンクする.

これらは Objective-C の環境では標準なのだろうか?

2009-06-14

Perl で強制的にリストコンテキストで評価する方法

Perl で強制的にスカラーコンテキストで評価するには scalar を用いるが,強制的にリストコンテキストで評価するための list (仮称) は用意されていない.

man perlfuncscalar の項によると,これは実質的には全く必要無いからだそうであるが,両コンテキストで異なる値を返す関数がリストコンテキストで返すリストの要素数を中間変数なしに知りたい場合に困る.

例えば文字列中の / の数を数えようと思って,

$n = scalar split "/", $s;

とすると,split がスカラーコンテキストで評価されることにより @_ の変更が副作用として起こってしまう.use warnings をしていると警告も出力される.そこで強制的にリストコンテキストで split を呼び,それを scalar に渡すようにすれば解決する.これには @{[...]} を用いる.

$n = scalar @{ [ split "/", $s ] };

[ ] はリストへのリファレンスを返し,その中はリストコンテキストで評価される.@{ } はリファレンスをリストに戻す.[ ] 内におく表現によってはそれを ( ) で囲む必要があるかもしれない.

今回の場合には適用できないが,単に (...) で済む場合が多い.

2009-06-10

git push の警告

git clone したものを単に引数なしで git push すると警告が出る.

warning: You did not specify any refspecs to push, and the current remote
warning: has not configured any push refspecs. The default action in this
warning: case is to push all matching refspecs, that is, all branches
warning: that exist both locally and remotely will be updated.  This may
warning: not necessarily be what you want to happen.
warning:
warning: You can specify what action you want to take in this case, and
warning: avoid seeing this message again, by configuring 'push.default' to:
warning:   'nothing'  : Do not push anything
warning:   'matching' : Push all matching branches (default)
warning:   'tracking' : Push the current branch to whatever it is tracking
warning:   'current'  : Push the current branch

リポジトリとブランチを指定しない git push は危険なので,次のメジャーリリースでは引数なしの動作が config されていない場合は拒否されるようになる.その予告として 1.6.3 から上記の長い警告が出るようになった.

回避するには push.default オプションを明示的に指定すればよい.

$ git config push.default matching

参考

With the next major release, "git push" into a branch that is
currently checked out will be refused by default.  You can choose
what should happen upon such a push by setting the configuration
variable receive.denyCurrentBranch in the receiving repository.

To ease the transition plan, the receiving repository of such a
push running this release will issue a big warning when the
configuration variable is missing.  Please refer to:

  http://git.or.cz/gitwiki/GitFaq#non-bare
  http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007

for more details on the reason why this change is needed and the
transition plan.