2008年12月アーカイブ

まだXSのことをよくわかってないのですが、XSモジュール用のModule::Setupのflavorを作ってみました。

このflavorを使うには、記事下にあるコードをXSFlavor.pmって名前でファイルに保存して、

% module-setup --init --flavor-class=+XSFlavor xs

でflavorを展開したら、あとは以下のようにするだけでXSモジュールの雛形ができあがります。

% module-setup Your::Module xs

このflaverでできる雛形のXSには、newとincrementっていう関数が最初から追加されているので、いらない場合はてきとうに編集してください。


このflavorを最初はModule::Starterで作ろうと思ってたんだけど、module-starterコマンドではflavorの使い分ける機能がないんですね。自分でそういうコマンドラインのを作ればいいんだけど、もうその機能が備わってるModule::Setupに切り替えちゃいました。

Module::Setupのflavor機能は素晴しいすなぁ。

以下がFlavorになります。

package XSFlavor;
use strict;
use warnings;
use base 'Module::Setup::Flavor';
1;

=head1

XSFlavor - pack from xs

=head1 SYNOPSIS

  XSFlavor-setup --init --flavor-class=+XSFlavor new_flavor

=cut

__DATA__

---
file: .shipit
template: |
  steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist, UploadCPAN
  svk.tagpattern = release-%v
---
file: ____var-module_file-var____.xs
template: |
  #ifdef __cplusplus
  extern "C" {
  #endif
  #include "EXTERN.h"
  #include "perl.h"
  #include "XSUB.h"
  #include "ppport.h"
  #ifdef __cplusplus
  }
  #endif
  
  typedef SV * [% module.replace('::', '_')%];
  
  MODULE = [% module %]		PACKAGE = [% module %]		
  
  [% module.replace('::', '_') %]
  new(...)
      INIT:
      	char *classname;
  	/* get the class name if called as an object method */
  	if ( sv_isobject(ST(0)) ) {
  	    classname = HvNAME(SvSTASH(SvRV(ST(0))));
  	}
  	else {
  	    classname = (char *)SvPV_nolen(ST(0));
  	}
  
      CODE:
      	/* This is a standard hash-based object */
      	RETVAL = ([% module.replace('::', '_') %])newHV();
  
  	/* Single init value */
  	if ( items == 2 ) 
  	    hv_store((HV *)RETVAL, "value", 5, newSVsv(ST(1)), 0);
  	/* name/value pairs */
  	else if ( (items-1)%2 == 0 ) {
  	    int i;
  	    for ( i=1; i < items; i += 2 ) {
  		hv_store_ent((HV *)RETVAL, ST(i), newSVsv(ST(i+1)), 0);
  	    }
  	}
  	/* odd number of parameters */
  	else {
  	    Perl_croak(aTHX_
  		"Usage: [% module %]->new()\n"
  		"    or [% module %]->new(number)\n"
  		"    or [% module %]->new(key => value, ...)\n"
  	    );
  	}
  
      OUTPUT:
      	RETVAL
  
  IV
  increment(obj)
      [% module.replace('::', '_') %] obj
  
      INIT:
         RETVAL = 0;
         if ( items > 1 )
             Perl_croak(aTHX_ "Usage: [% module %]->increment()");
  
      CODE:
         SV **svp;
         if ((svp = hv_fetch((HV*)obj, "value", 5, FALSE))) {
             RETVAL = SvIV(*svp);
             RETVAL++;
             hv_store((HV *)obj, "value", 5, newSViv(RETVAL), 0);
         }
      OUTPUT:
         RETVAL
---
file: Changes
template: |
  Revision history for Perl extension [% module %]
  
  0.01    [% localtime %]
          - original version
---
file: Makefile.PL
template: |+
  use inc::Module::Install;
  
  name     '[% dist %]';
  all_from 'lib/[% module_path %].pm';
  
  # requires '';
  
  tests 't/*.t';
  author_tests 'xt';
  
  cc_inc_paths '.';
  can_cc or die 'This module requires a C compiler';
  
  build_requires 'Test::More';
  use_test_base;
  auto_include;
  WriteAll;
  
  sub MY::post_constants {
      return <<"POST_CONST";
  XSUBPPARGS += -typemap typemap
  POST_CONST
  }

---
file: MANIFEST.SKIP
template: |
  \bRCS\b
  \bCVS\b
  ^MANIFEST\.
  ^Makefile$
  ~$
  ^#
  \.old$
  ^blib/
  ^pm_to_blib
  ^MakeMaker-\d
  \.gz$
  \.cvsignore
  ^t/9\d_.*\.t
  ^t/perlcritic
  ^tools/
  \.svn/
  ^[^/]+\.yaml$
  ^[^/]+\.pl$
  ^\.shipit$
---
file: README
template: |
  This is Perl module [% module %].
  
  INSTALLATION
  
  [% module %] installation is straightforward. If your CPAN shell is set up,
  you should just be able to do
  
      % cpan [% module %]
  
  Download it, unpack it, then build it as per the usual:
  
      % perl Makefile.PL
      % make && make test
  
  Then install it:
  
      % make install
  
  DOCUMENTATION
  
  [% module %] documentation is available as in POD. So you can do:
  
      % perldoc [% module %]
  
  to read the documentation online with your favorite pager.
  
  [% config.author %]
---
file: typemap
template: |
  ###############################################################################
  ##
  ##    Typemap for [% module %] objects
  ##
  ##    Copyright (c) [% config.author %]
  ##    All rights reserved.
  ##
  ##    This typemap is designed specifically to make it easier to handle
  ##    Perl-style blessed objects in XS.  In particular, it takes care of
  ##    blessing the object into the correct class (even for derived classes).
  ##
  ##
  ###############################################################################
  ## vi:et:sw=4 ts=4
  
  TYPEMAP
  
  [% module.replace('::', '_') %] T_PTROBJ_SPECIAL
  
  INPUT
  T_PTROBJ_SPECIAL
      if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")) {
  	$var = SvRV($arg);
      }
      else
  	croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")
  
  OUTPUT
  T_PTROBJ_SPECIAL
      /* inherited new() */
      if ( strcmp(classname,\"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\") != 0 )
  	$arg = sv_bless(newRV_noinc($var),
  	    gv_stashpv(classname,TRUE));
      else
  	$arg = sv_bless(newRV_noinc($var),
  	    gv_stashpv(\"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\",TRUE));
---
file: lib/____var-module_path-var____.pm
template: |
  package [% module %];
  
  use strict;
  use warnings;
  #use base qw(Exporter);
  #our @EXPORT_OK = ();
  
  our $VERSION = '0.01';
  
  require XSLoader;
  XSLoader::load(__PACKAGE__, $VERSION);
  
  1;
  __END__
  
  =head1 NAME
  
  [% module %] -
  
  =head1 SYNOPSIS
  
    use [% module %];
  
  =head1 DESCRIPTION
  
  [% module %] is
  
  =head1 AUTHOR
  
  [% config.author %] E<lt>[% config.email %]E<gt>
  
  =head1 SEE ALSO
  
  =head1 LICENSE
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself.
  
  =cut
---
file: t/00_compile.t
template: |
  use strict;
  use Test::More tests => 1;
  
  BEGIN { use_ok '[% module %]' }
---
file: xt/01_podspell.t
template: |
  use Test::More;
  eval q{ use Test::Spelling };
  plan skip_all => "Test::Spelling is not installed." if $@;
  add_stopwords(map { split /[\s\:\-]/ } <DATA>);
  $ENV{LANG} = 'C';
  all_pod_files_spelling_ok('lib');
  __DATA__
  [% config.author %]
  [% config.email %]
  [% module %]
---
file: xt/02_perlcritic.t
template: |
  use strict;
  use Test::More;
  eval {
      require Test::Perl::Critic;
      Test::Perl::Critic->import( -profile => 'xt/perlcriticrc');
  };
  plan skip_all => "Test::Perl::Critic is not installed." if $@;
  all_critic_ok('lib');
---
file: xt/03_pod.t
template: |
  use Test::More;
  eval "use Test::Pod 1.00";
  plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
  all_pod_files_ok();
---
file: xt/perlcriticrc
template: |
  [TestingAndDebugging::ProhibitNoStrict]
  allow=refs
---
plugin: plugin.pm
template: |
  package XSFlavor::Plugin;
  use strict;
  use warnings;
  use base 'Module::Setup::Plugin';
  use Devel::PPPort;
  use File::Spec;
  
  sub register {
      my $self = shift;
      $self->add_trigger( after_create_skeleton => \&create_ppport_process );
      $self->add_trigger( after_setup_template_vars => \&add_template_vars );
  }
  
  sub create_ppport_process {
      my $self = shift;
      $self->log( "Creating ppport.h" );
      Devel::PPPort::WriteFile(
          File::Spec->catfile( $self->distribute->dist_path, 'ppport.h' )
      );
  }
  
  sub add_template_vars {
      my ( $self, $template_vars ) = @_;
      my ( $module_file ) = $template_vars->{ module } =~ m#(?:.*::)?(.*)$#;
      $template_vars->{ module_file } = $module_file;
  }
  
  1;
---
config:
  plugins:
    - Config::Basic
    - Template
    - Test::Makefile
    - Additional
    - +XSFlavor::Plugin
以前「予約したシュウォッチ」がついに届いたのでご報告します。

パッケージはこんな感じ。

シュウォッチのパッケージ

開けてみたらこんな感じ
このフォルムがものすごい懐しいんですけど!

シュウォッチ

さっそくやってみましたが100に届きませんでしたorz
ちなみにこすりでなく純粋な高橋名人打ちでこんなかんじでした。
昔はこすりで200オーバーは軽かったんだけどなー。

もうちょっと精進して、いい値が出たら報告しようと思います。

あと1つ気になったのが液晶画面の下の右2つが?になっていて、
これって確かシークレットモードだったと思うのですが、これの出現条件ってなんでしたっけ...?

1つは「160打を越えればいい」だったような気がするんですが。
もう1つが思い出せない。
って検索すれば出てきそうなのであとで調べてみよう。

あるC言語で書かれたプログラムのソースを見ててu_intとかu_charとかいう方があって、これってなんだろうと思ったので調べてみた。

Mac OS X(Leopard)だと/usr/include/sys/types.hに答えが。

typedef unsigned char           u_char;
typedef unsigned short          u_short;
typedef unsigned int            u_int;

なるほど。unsigned intやunsigned charのエイリアスなんだね。

ちなみにCentOSとTurboLinuxだと/usr/include/sys/types.hには

typedef __u_char u_char;
typedef __u_short u_short;
typedef __u_int u_int;

と書いてあって、__u_charとかは/usr/include/bits/types.hに

typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;

って書いてありました。

Terminal.appでOutputzが使えるっていうので設定してみた。
Terminal.appでEmacs使ってoutputz.el入れてたら重複しちゃうのかな?

今のところoutputz.elは入れてないのでとりあえず考えないことにする。

昨日書いた「正規表現を入れておく変数の名前」ですが、なんと58人も答えてくれた。
みんなありがとう><

で結果はというと、当初選択肢に入ってなかった「$re」が多いという結果になっていて、その後を$regexが追う形になってます。

なるほど、次から正規表現を入れるときは「$re」にしてみよう。

世の中のMoose期が過ぎ去った感がある今日この頃ですが、ここにきてやっとMooseをさわりはじめました。

なんで突然Mooseをさわりはじめたかというと、typesterkamaitachiをちょっと使ってみようと思って見ていたらMooseを使っていて、まずMooseがわからないとコードが読めなかったからです。

ということで、ファーストインプレッションは以下。

  • hasとかextendsはなんとなくわかる
  • use Moose;するとuse strict;やuse warnings;が必要ないんだね
  • no Moose;している理由ってhasとかextendsとかのメソッド(pod内でkeywordと書かれているもの)をそれ以降で使えないようにしたいからなのね
  • __PACKAGE__->meta->make_immutable;はそのクラスをimmutableにして、memorizeすることによりMooseの速度を上げる
  • Mooseを使ったモジュールの最後に1;ってやってないのあって、変わりに__PACKAGE__->meta->make_immutable;してる
  • なんか日本語のドキュメントが少ない。Moose::Cookbookがけっこう充実してるのでまずはその辺を読めばいいかも
  • sub BUILD {} ってのがあってMoose的にはnew()は書き換えないで、その代わりにBUILD()を使うらしい
  • use Moose;するとそのクラスがMoose::Objectの子クラスいなる(という動作の原理をあとで調べたい)
以下参考にしたページ
http://blog.yappo.jp/yappo/archives/000579.html
http://d.hatena.ne.jp/tokuhirom/20080504/1209891158
http://d.hatena.ne.jp/fbis/20080814/1218689670
http://d.hatena.ne.jp/fbis/20080815/1218776733
http://perl-mongers.org/2008/05/moose.html
http://mt.endeworks.jp/d-6/2008/07/moose.html
http://trombik.mine.nu/~cherry/w/index.php/2008/03/22/1202/oop-with-moose

$foo = qr/blah/;

こんなときの$fooをなんて名前にするのか。

ちょっと気になったので聞いてみた。




今これを書いてる段階では$regexが優勢ですね。

自分はいつも$regexか$regexpか悩むんだけど、誰かが選択肢に追加した$reとかちょっと好きかも。

でもこの$で始まる書き方だと言語が限定されちゃうから聞きかたをちょっと間違えた感あり…。

興味があったら答えてください。
MacでEmacsを使うときは、Carbon Emacsを使ったりTerminal.appで使ったりしてるんですが、Carbon EmacsではCmd-vでPage Upできるのに、Terminal.appのEmacsだとそれができなかったのです。

これを直すには2つやらなきゃならないことがあって今回それをやったのでメモっておく。

1つは、KeyRemap4MacBookでTerminal.appのときだけ左Commandを左Optionにする(詳しくはこちら)。もう1つは、Terminal.appの設定で「メタキーとして option キーを使用」にチェックを入れる。

この2つを設定すると、やっとTerminal.appのEmacsでCmd-vでPage Upすることができるようになります。

教訓:
設定をよくみろ。

ということでtypesterさん、ご協力ありがとうございました。

#左のCommandキーが使えなくなったので、しばらくは間違えてコピペ
#しちゃいそうだけどそれは徐々に慣れるだろう…。

ついに日本での発売が決定したEye-Fiですが、Amazonなどで先行予約が始まってるのでちょっと悩んだ末、結局買うんだしということで予約しちゃった!

発送が12/31〜とか書いてあるんだけど年内に届けばいいんだけどなぁ。

Eye-Fi Share 2GB ワイヤレスSDメモリ 日本版(正規品) 先行予約販売
Eye-Fi Inc
売り上げランキング: 69
おすすめ度の平均: 5.0
5 待望の日本正規版!
feedburnerの設定を間違えていて、ここ一ヶ月更新したものをLDRとかにフェッチされてなかったorz ということでLDRとか使ってた方、お久しぶりです。
今日、突然QuickSilverが落ちるようになってしまいました。

具体的にどう落ちるようになったかというと、自分はログイン時にQuickSilverを起動するようにしているのですが、ログインにQuickSilverが一旦起動して直後にアラートを出して落ちてしまいます。

しかたがないので再度手動で起動してみるも1分もしないうちに、またアラートを出して落ちてしまいます。

ちなみにConsoleを見ると

[0x0-0x48048].com.blacktree.Quicksilver[341] Quicksilver(341,0xa021ffa0) malloc: *** mmap(size=1645342720) failed (error code=12)
[0x0-0x48048].com.blacktree.Quicksilver[341] *** error: can't allocate region
[0x0-0x48048].com.blacktree.Quicksilver[341] *** set a breakpoint in malloc_error_break to debug

こんなエラーです。

で、とりあえずググってみたら解決方法が見付かりました。このGoogle CodeのQuickSilverのIssue Trackerに書いてありました。

結論としてはQuickSilverのPasteboard History用のファイルに巨大なデータが入ってしまっていたからで、下記のように $HOME/Library/Application Support/Quicksilver/Shelves/QSPasteboardHistory.qsshelf を削除すれば解決します。

% cd ~/Library/Application\ Support/Quicksilver/Shelves/
% ls -lh QSPasteboardHistory.qsshelf
-rw-r--r--  1 username  staff   785M Dec  5 14:50 QSPasteboardHistory.qsshelf

ちなみに自分の QSPasteboardHistory.qsshelf の容量を見てみたら785MBもありました。ひょえー。なんでこんなに貯まってたのかわかりませんがものすごい量ですね。さらにさらに中身を見たらぜんぶテキストデータだったので、どんだけ貯まってるんだって感じです。

ということで、これを削除してQuickSilverを起動しなおしたら落ちることもなくなりました。

必ずしもこの方法で直るとは言えませんが、1つの方法としてメモしておきます。

dateコマンドで今の時刻の1日前とかを求めるのってよくやると思いますが、
dateコマンドはOSによって方言があってオプションをいつも忘れて毎回調べたりしてるので
メモがわりに書いておりきます。

1日前をもとめたいときは?

BSD系
% date -v-1d

Linux系
% date --date '1 days ago'


1日前をもとめつつフォーマットを整えたいときは?

BSD系
% date -v-1d +%Y%m%d

Linux系
% date --date '1 days ago' +%Y%m%d


ある指定した日の1日前とかを求める方法。

BSD系
% date -j -v-1d -f %Y%m%d 20081201 +%Y%m%d

※この「-j」を付け忘れるとシステムの時間が変わっちゃうので注意
Linux系
% date --date '20081201 1days ago'


とこんな感じ。

関連エントリ:
crontabで月末に実行させたし

検索

広告

月別 アーカイブ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.12