2013-03-25

[戯言]ブログ移行します

本ブログを3年やってきました。

ですが、このBloggerはでブログ記事を書くのは辛いです。。。

編集しづらいことが苦行でした。

そのため、markdownで記事が記述できるOctpressにこの度移行することにしました。
記事も気に入ったものというか、役に立つものから順に移行していきます。多分。
当面、記事を削除する予定はないですが、気が変わったら削除します。

新ブログ
http://moonstruckdrops.github.com

 以上

2013-02-28

[AppEngine]AppEngineでbyte配列を扱う

表題のことをするだけなんだが、苦労した。
普通に文字列をbyte配列に変換して、更に元に戻す場合だとこんな感じにやると思います。
byte[] data = "hoge".getBytes();
String str = new String(data);


ただ、これだとローカル環境だと問題無く使えますが、本番環境だとうまく扱えなくなります。

何故かというとAppEngineでは、Protocol Buffersを使用してるからです。
どうやら、Protocol Buffersでは、byte配列の扱いが異なるようです。
特にGoogleのサービスを扱う場合、特に注意したほうがよいでしょう。
自分は、UrlFetchサービスで困りました(文字化けが盛大に起こっていたなど)
他にもbyte配列を扱うようなサービスDatastoreサービスでも文字化けが起こるような可能性は高いでしょう。

というわけで、こんな感じでProtocol Buffersを使えばよいですね。
ByteString copyFrom = ByteString.copyFromUtf8(data);
byte[] byteData = copyFrom.toByteArray();


これで、byte配列に変換しても困ることなく扱えますね。

2013-02-25

[Android]APIに変更を入れた場合のビルドは更新コマンドが必要


1年ぶりにAOSPに貢献してみました。。。

▲経緯
Androidのソースコードは、ドキュメントと機能が一致していないようなことが結構あったりします。
下手をすると、ドキュメントが何も記載されていないメソッドなり機能だったりがあります。
# もしかしたら自分の英語の読解力が無いだけかもしれまんせんが。

そういうわけで、自分の拙い英語力だけどドキュメントでも書いてあげればいいんじゃねーのとか思うわけです。
# 同じように困ってるような人はいると思いますので・・・

というわけで、ドキュメントを少し書いてみた。(一部、APIも変えてみましたが)
よし、ビルドが通ればコミットするぞ・・・と息巻いてたところビルドでコケるというような事象がありました。

▲解決
エラーログにapiを更新するようなコマンド叩いてみるといいよと出てますので実行します。

$make update-api

それから再度ビルドを実施します。
$make -j4

一応、以下にエラーログを記載しておきます(抜粋)
Checking API: checkapi-current
Compiling SDK Stubs: out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes.jar
out/target/common/obj/PACKAGING/public_api.txt:11256: error 21: Method 

******************************
You have tried to change the API from what has been previously approved.

To make these errors go away, you have two choices:
   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
      errors above.

   2) You can update current.txt by executing the following command:
         make update-api

      To submit the revised current.txt to the main Android repository,
      you will need approval.
******************************



make: *** [out/target/common/obj/PACKAGING/checkapi-current-timestamp] Error 38
make: *** Waiting for unfinished jobs....
 'out/target/common/obj/APPS/Settings_intermediates/classes.dex' as 'classes.dex'...
out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/java/security/cert/PKIXBuilderParameters.java:5: ?x??:[unchecked] ???????ϊ??ł?

2013-01-27

[Linux]CentOSの開発環境を見なおしてた。。。

先月から色々ドタバタだった。
ようやく(?)少し落ち着いたかもしれない。。。

落ち着いたかもしれないところで開発に使用しているCentOSの環境を見なおしてみた。。。

なんで見なおしてみたかったかというと、

「/usr/localにインストールしているアプリケーション類のパッケージ管理をrpmにしたかった。」

ただ、それだけなんですけど。乱立しているのは避けたいところ(公式だと古いものが多かったりで入れなおしたりとか)
とは言ったものの、できないものもあるわけで・・・(eclipseとかandroidとか)

▲エディタ
ViとかVimは最低限のレベルでしか使えない人なのでEmacsが欲しいところ。
とはいえ、パッケージ管理があったりしてる24.1以上が欲しい。(単につかうだけなら公式から23.3だっけを入れればいいのですが)

rpmビルドしたEmacsをインストールします。

ビルド方法
http://moonstruckdrops.blogspot.jp/2012/12/linuxrpmspecemacs.html

▲bash_completion
こいつないと、コマンドの補完周りが貧弱になるので必須。

という訳でEPELからインストールしましょう。
$wget http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
$rpm -Uvh epel-release-6-8.noarch
$yum --enablerepo=epel check-update
$yum --enablerepo=epel install bash_completion

EPEL
http://fedoraproject.org/wiki/EPEL

▲ターミナル
GNU Screenだと分割周りがつらかったりするので、tmuxを入れます。

というわけで、配布してるRepoforge(Rpmforge)をインストールしてからtmuxをインストールします

$wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$rpm -Uvh rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$yum --enablerepo=rpmforge check-update
$yum --enablerepo=rpmforge install tmux

▲ブラウザ
Firefoxで一応、実用上十分なんだけど、JSの実装とか細かい違いとかで新しいものがやっぱり欲しいところ。
というわけで、Chromeが欲しいですね。

Google RPM Packages
http://www.google.com/linuxrepositories/

一応、ThirdPartyを使えばFirefox18も入れれることができます。(Remiリポジトリ)

$rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
$yum --enablerepo=remi list firefox
$yum --enablerepo=remi update firefox

▲Java
Oracleからパッケージをダウンロードしてインストール

eclipseとandroidはどうにもならないので諦めましょう。
(/usr/local/shareにいれて、シンボリックリンクを/usr/local/binにつけるとかで対処かな)

▲Ruby
rbenv+ruby-buildを組み合わせてやればいいでしょう。
欲しいライブラリなどはgemで一発インストール。

rbenv
https://github.com/sstephenson/rbenv

ruby-build
https://github.com/sstephenson/ruby-build

※インストール方法とか設定は今度書くかもしれない

▲Python

公式が2.6と古いの2.7系にしたい(今はアーリーアダプタな方たちの3系とかもそのうち使うかも)

rpmを作成してインストールしましょう
%define binsuffix 2.7
%define libvers 2.7
# 一括置換で修正
%define libdirname lib

Summary: An interpreted, interactive, object-oriented programming language.
Name: python27
Version: 2.7.2
Release: %{?dist}.3
License: PSF
Group: Development/Languages
Source: Python-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: gcc make expat-devel db4-devel gdbm-devel sqlite-devel readline-devel zlib-devel bzip2-devel openssl-devel
AutoReq: no
Vendor: kurobara
Packager: kurobara

%description
Python is an interpreted, interactive, object-oriented programming
language. It incorporates modules, exceptions, dynamic typing, very high
level dynamic data types, and classes. Python combines remarkable power
with very clear syntax. It has interfaces to many system calls and
libraries, as well as to various window systems, and is extensible in C or
C++. It is also usable as an extension language for applications that need
a programmable interface. Finally, Python is portable: it runs on many
brands of UNIX, on PCs under Windows, MS-DOS, and OS/2, and on the
Mac.

%package devel
Summary: The libraries and header files needed for Python extension development.
Requires: %{name} = %{version}-%{release}
Group: Development/Libraries

%description devel
The Python programming language's interpreter can be extended with
dynamically loaded extensions and can be embedded in other programs.
This package contains the header files and libraries needed to do
these types of tasks.

Install python-devel if you want to develop Python extensions. The
python package will also need to be installed. You'll probably also
want to install the python-docs package, which contains Python
documentation.

### tkinterが有効時にコメントアウトを外す
#%package tkinter
#Summary: A graphical user interface for the Python scripting language.
#Group: Development/Languages
#Requires: %{name} = %{version}-%{release}

#%description tkinter
#The Tkinter (Tk interface) program is an graphical user interface for
#the Python scripting language.
#
#You should install the tkinter package if youd like to use a graphical
#user interface for Python programming.


%package tools
Summary: A collection of development tools included with Python.
Group: Development/Tools
Requires: %{name} = %{version}-%{release}

%description tools
The Python package includes several development tools that are used
to build python programs. This package contains a selection of those
tools, including the IDLE Python IDE.

Install python-tools if you want to use these tools to develop
Python programs. You will also need to install the python and
tkinter packages.

%prep
%setup -n Python-%{version}

### BUILD
%build
%configure \
--enable-unicode=ucs4 \
--with-signal-module \
--with-threads \
--enable-shared \
--with-pymalloc \
--enable-ipv6 \
--prefix=%{_prefix}

%{__make} %{?_smp_mflags}

##########
# INSTALL
##########
%install
# set the install path
echo '[install_scripts]' >setup.cfg
echo 'install_dir='"${RPM_BUILD_ROOT}%{_prefix}/bin" >>setup.cfg

[ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/lib-dynload
#%{__make} prefix=$RPM_BUILD_ROOT%{__prefix} altinstall
%{__make} altinstall DESTDIR="%{buildroot}"

### REPLACE PATH IN PYDOC
cd $RPM_BUILD_ROOT%{_prefix}/bin
mv pydoc pydoc.old
sed 's|#!.*|#!%{_prefix}/bin/python'%{binsuffix}'|' pydoc.old >pydoc
chmod 755 pydoc
rm -f pydoc.old
sed -i -e 's|#!.*|#!%{_prefix}/bin/python'%{binsuffix}'|' python%{libvers}-config
### add the binsuffix
cd $RPM_BUILD_ROOT%{_prefix}/bin;
for file in 2to3 pydoc python-config idle smtpd.py; do
    [ -f "$file" ] && mv "$file" "$file"%{binsuffix};
done;

# Fix permissions
# 64bit
#chmod 644 $RPM_BUILD_ROOT%{_prefix}/%{libdirname}64/libpython%{libvers}*
# 32bit
chmod 644 $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/libpython%{libvers}*
########
# Tools
cd $RPM_BUILD_DIR/Python-%{version}
cp -a Tools $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}

### Makefileのインストール
cd $RPM_BUILD_DIR/Python-%{version}
mkdir -p $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/config
#chmod 644 $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/config
%{__install} -p -m0644 Makefile $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/config

# MAKE FILE LISTS
rm -f mainpkg.files
find "$RPM_BUILD_ROOT""%{_prefix}"/%{libdirname}/python%{libvers} -type f |
sed "s|^${RPM_BUILD_ROOT}|/|" | grep -v -e '_tkinter.so$' >mainpkg.files
find "$RPM_BUILD_ROOT""%{_prefix}"/bin -type f -o -type l |
sed "s|^${RPM_BUILD_ROOT}|/|" |
grep -v -e '/bin/2to3%{binsuffix}$' |
grep -v -e '/bin/pydoc%{binsuffix}$' |
grep -v -e '/bin/smtpd.py%{binsuffix}$' |
grep -v -e '/bin/idle%{binsuffix}$' >>mainpkg.files
echo %{_prefix}/include/python%{libvers}/pyconfig.h >> mainpkg.files

rm -f tools.files
echo "%{_prefix}"/%{libdirname}/python%{libvers}/Tools >>tools.files
echo "%{_prefix}"/%{libdirname}/python%{libvers}/lib2to3/tests >>tools.files
echo "%{_prefix}"/bin/2to3%{binsuffix} >>tools.files
echo "%{_prefix}"/bin/pydoc%{binsuffix} >>tools.files
echo "%{_prefix}"/bin/smtpd.py%{binsuffix} >>tools.files
echo "%{_prefix}"/bin/idle%{binsuffix} >>tools.files


# fix the #! line in installed files
find "$RPM_BUILD_ROOT" -type f -print0 |
      xargs -0 grep -l /usr/local/bin/python | while read file
do
   FIXFILE="$file"
   sed 's|^#!.*python|#!%{_prefix}/bin/python'"%{binsuffix}"'|' \
         "$FIXFILE" >/tmp/fix-python-path.$$
   cat /tmp/fix-python-path.$$ >"$FIXFILE"
   rm -f /tmp/fix-python-path.$$
done

########
# CLEAN
########
%clean
[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT
rm -f mainpkg.files tools.files

########
# FILES
########
%files -f mainpkg.files
%defattr(-,root,root)
%doc Misc/README Misc/cheatsheet Misc/Porting
%doc LICENSE Misc/ACKS Misc/HISTORY Misc/NEWS

# OMG I'm a Lazy hack.
%{_prefix}/lib/python2.7/lib-dynload/
# 64bit
#%{_prefix}/lib64/python2.7/lib-dynload/
#%{_prefix}/lib64/pkgconfig/python-2.7.pc
# 32bit
%{_prefix}/lib/python2.7/lib-dynload/
%{_prefix}/lib/pkgconfig/python-2.7.pc



%attr(755,root,root) %dir %{_prefix}/include/python%{libvers}
%attr(755,root,root) %dir %{_prefix}/lib/python%{libvers}/
%attr(755,root,root) %dir %{_prefix}/%{libdirname}/python%{libvers}/

### ライブラリ
# 64bit
#%{_prefix}/%{libdirname}64/libpython*
# 32bit
%{_prefix}/%{libdirname}/libpython*

%files devel
%defattr(-,root,root)
%{_prefix}/include/python%{libvers}/*.h
# 64bit
#%{_prefix}/%{libdirname}64/python%{libvers}/config
# 32bit
%{_prefix}/%{libdirname}/python%{libvers}/config

%files -f tools.files tools
%defattr(-,root,root)

### tkinterが有効時にコメントアウトを外す
#%files tkinter
#%defattr(-,root,root)
#%{__prefix}/%{libdirname}/python%{libvers}/lib-tk
#%{__prefix}/%{libdirname}64/python%{libvers}/lib-dynload/_tkinter.so*


▲DB
Postgeresqlを使うこともあるでしょう。。。
rpmのサイトからリポジトリ先をダウンロードしてインストールしてからyumでインストール

PostgreSQL RPM Building Project
http://yum.postgresql.org/repopackages.php

MySQLを使うこともあるでしょう。。。

$yum install mysql-server

新しいものが欲しい場合、ミラーからrpmを個別にダウンロードして
インストールすればいいかもしれないですね。

MySQL mirrorリスト
http://dev.mysql.com/downloads/mirrors.html

▲バージョン管理
流行りのGitを使いたいところ
公式のバージョンは古杉なので、自分でrpmを作成してインストールしましょう。
とは言え、Subversionを使ってるところも多いので一応インストールします。(git-svnでも使いますからね)
$yum install subversion

git.spec
%define perl_vendorlib %(eval "`%{__perl} -V:installvendorlib`"; echo $installvendorlib)
%define perl_vendorarch %(eval "`%{__perl} -V:installvendorarch`"; echo $installvendorarch)

%define desktop_vendor kurobara

Summary: Git core and tools
Name: git
Version: 1.8.1.1
Release: %{?dist}.3
License: GPL
Group: Development/Tools
URL: http://git-scm.com/

Packager: kurobara
Vendor: kurobara

Source0: https://git-core.googlecode.com/files/git-%{version}.tar.gz
Source1: gitweb.conf.in
BuildRoot: %{_tmppath}/%{name}-%{version}-root

BuildRequires: asciidoc > 6.0.3
BuildRequires: curl-devel >= 7.9
BuildRequires: desktop-file-utils
BuildRequires: expat-devel
BuildRequires: gettext
BuildRequires: emacs
BuildRequires: openssl-devel
BuildRequires: perl(ExtUtils::MakeMaker)
BuildRequires: xmlto
BuildRequires: zlib-devel >= 1.2
Requires: less
Requires: openssh-clients
Requires: perl-Git = %{version}-%{release}
Requires: rsync
Requires: zlib >= 1.2

Obsoletes: git-core <= %{version}-%{release}
Provides: git-core = %{version}-%{release}

%description
GIT comes in two layers. The bottom layer is merely an extremely fast
and flexible filesystem-based database designed to store directory trees
with regard to their history. The top layer is a SCM-like tool which
enables human beings to work with the database in a manner to a degree
similar to other SCM tools (like CVS, BitKeeper or Monotone).

%package all
Summary: Meta-package to pull in all git tools
Group: Development/Tools
Requires: emacs-git = %{version}-%{release}
Requires: git = %{version}-%{release}
Requires: git-arch = %{version}-%{release}
Requires: git-cvs = %{version}-%{release}
Requires: git-email = %{version}-%{release}
Requires: git-gui = %{version}-%{release}
Requires: git-svn = %{version}-%{release}
Requires: gitk = %{version}-%{release}
Requires: perl-Git = %{version}-%{release}
Obsoletes: git <= 1.5.4.3

%description all
Git is a fast, scalable, distributed revision control system with an
unusually rich command set that provides both high-level operations
and full access to internals.

This is a dummy package which brings in all subpackages.

%package arch
Summary: Git tools for importing Arch repositories
Group: Development/Tools
Requires: %{name} = %{version}-%{release}

%description arch
Git tools for importing Arch repositories.

%package cvs
Summary: Git tools for importing CVS repositories
Group: Development/Tools
Requires: cvs
Requires: cvsps
Requires: %{name} = %{version}-%{release}

%description cvs
Git tools for importing CVS repositories.

%package daemon
Summary: Git protocol daemon
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: xinetd

%description daemon
The git daemon for supporting git:// access to git repositories

%package email
Summary: Git tools for sending email
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: perl-Git = %{version}
Requires: perl(Authen::SASL::Perl)
Requires: perl(Email::Valid)
Requires: perl(Mail::Address)
Requires: perl(Net::Domain)
Requires: perl(Net::SMTP::SSL)
Requires: perl(Sys::Hostname)

%description email
Git tools for sending email.

%package gui
Summary: Graphical frontend to git
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: tk >= 8.4
Requires: gitk = %{version}-%{release}

%description gui
Graphical frontend to git.

%package svn
Summary: Git tools for importing Subversion repositories
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: perl(Error)
Requires: perl(Term::ReadKey)
Requires: subversion

%description svn
Git tools for importing Subversion repositories.

%package -n emacs-git
Summary: Git version control system support for Emacs
Group: Applications/Editors
Requires: %{name} = %{version}-%{release}
Requires: emacs-common

%description -n emacs-git
%{summary}.

%package -n gitk
Summary: Git revision tree visualiser
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: tk >= 8.4

%description -n gitk
Git revision tree visualiser.

%package -n gitweb
Summary: Simple web interface to git repositories
Group: Development/Tools
Requires: %{name} = %{version}-%{release}

%description -n gitweb
Simple web interface to track changes in git repositories

%package -n perl-Git
Summary: Perl module that implements Git bindings
Group: Applications/CPAN
### 以下の理由でコメントアウト
### 動作に必要という点ではgitに依存する
### 設定した場合にgitそのものがインストールできなくなる
#Requires: %{name} = %{version}-%{release}

%description -n perl-Git
Git is a Perl module that implements Git bindings.

%prep
%setup

%{__cat} <config.mak
V = 1
CFLAGS = %{optflags}
BLK_SHA1 = 1
NEEDS_CRYPTO_WITH_SSL = 1
NO_PYTHON = 1
ETC_GITCONFIG = %{_sysconfdir}/gitconfig
DESTDIR = %{buildroot}
INSTALL = install -p
GITWEB_PROJECTROOT = %{_localstatedir}/lib/git
htmldir = %{_docdir}/%{name}-%{version}
prefix = %{_prefix}
INSTALLDIRS = vendor
mandir = %{_mandir}
WITH_OWN_SUBPROCESS_PY = YesPlease
ASCIIDOC_EXTRA = --unsafe
EOF

### gitdaemonの設定
### gitdaemon用のxファイルを生成
%{__cat} <git.xinetd
# default: off
# description: The git daemon allows git repositories to be exported using \
#       the git:// protocol.

service git
{
        disable         = yes

        # git is in /etc/services only on RHEL5+
        #type            = UNLISTED
        #port            = 9418

        socket_type     = stream
        wait            = no
        user            = nobody
        server          = %{_libexecdir}/git-core/git-daemon
        server_args     = --base-path=%{_localstatedir}/lib/git --export-all --user-path=public_git --syslog --inetd --verbose
        log_on_failure  += USERID
        # xinetd does not enable IPv6 by default
        # flags           = IPv6
}
EOF

### gitguiの設定
### gitgui.desktopの生成
%{__cat} <git-gui.desktop
[Desktop Entry]
Name=Git GUI
GenericName=Git GUI
Comment=A graphical interface to Git
Exec=git gui
Icon=%{_datadir}/git-gui/lib/git-gui.ico
Terminal=false
Type=Application
Categories=Development;
EOF

### gitwebの設定
### gitweb.httpdの生成
%{__cat} <gitweb/gitweb.httpd
Alias /git %{_datadir}/gitweb


    Options +ExecCGI
    AddHandler cgi-script .cgi
    DirectoryIndex gitweb.cgi
EOF
### gitweb.confの生成
%{__sed} -e "s|@PROJECTROOT@|%{_localstatedir}/lib/git|g" %{SOURCE1} >gitweb.conf

### RPMインストール設定
### インストール時に設定される不要な依存を削除する
cat << \EOF > %{name}-req
#!/bin/sh
%{__perl_requires} $* |\
sed -e '/perl(packed-refs)/d'
EOF

%global __perl_requires %{_builddir}/%{name}-%{version}/%{name}-req
chmod +x %{__perl_requires}


%build
%{__make} %{?_smp_mflags} all

# bah, DocBook validation errors
%{__perl} -pi -e 's|^XMLTO_EXTRA =\s*$|XMLTO_EXTRA = --skip-validation \n|;' Documentation/Makefile

%{__make} %{?_smp_mflags} doc

## Perl preparation
cd perl
%{__perl} Makefile.PL DESTDIR="%{buildroot}" PREFIX="%{_prefix}"  INSTALLDIRS=%{perl_vendorlib}
%{__make} %{?_smp_mflags}
cd -

# Remove shebang from bash-completion script
sed -i '/^#!bash/,+1 d' contrib/completion/git-completion.bash

%install
### 初期化の実施
%{__rm} -rf %{buildroot}
### git installation
%{__make} install install-doc DESTDIR="%{buildroot}"
%{__make} -C contrib/emacs install emacsdir="%{buildroot}%{_datadir}/emacs/site-lisp"
for elc in %{buildroot}%{_datadir}/emacs/site-lisp/*.elc; do
    %{__install} -p -m0644 contrib/emacs/$(basename $elc .elc).el %{buildroot}%{_datadir}/emacs/site-lisp/
done
#%{__install} -Dp -m0644 %{SOURCE1} %{buildroot}%{_datadir}/emacs/site-lisp/site-start.d/git-init.el

### perl-Git installation
### perlモジュールのインストールでエラーが出ていたので個別にインストールする
%{__install} -p -m0644 perl/blib/lib/Git.pm %{buildroot}/usr/share/perl5/Git.pm
%{__install} -p -m0644 perl/blib/lib/Git/I18N.pm %{buildroot}/usr/share/perl5/Git/I18N.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Editor.pm %{buildroot}/usr/share/perl5/Git/SVN/Editor.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Fetcher.pm %{buildroot}/usr/share/perl5/Git/SVN/Fetcher.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Memoize/YAML.pm %{buildroot}/usr/share/perl5/Git/SVN/Memoize/YAML.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Prompt.pm %{buildroot}/usr/share/perl5/Git/SVN/Prompt.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Ra.pm %{buildroot}/usr/share/perl5/Git/SVN/Ra.pm
%{__install} -p -m0644 perl/blib/lib/Git/IndexInfo.pm %{buildroot}/usr/share/perl5/Git/IndexInfo.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN.pm %{buildroot}/usr/share/perl5/Git/SVN.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/GlobSpec.pm %{buildroot}/usr/share/perl5/Git/SVN/GlobSpec.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Log.pm %{buildroot}/usr/share/perl5/Git/SVN/Log.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Migration.pm %{buildroot}/usr/share/perl5/Git/SVN/Migration.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Utils.pm %{buildroot}/usr/share/perl5/Git/SVN/Utils.pm

### gitweb installation
%{__install} -d -m0755 %{buildroot}%{_localstatedir}/www/git/static/
%{__install} -p -m0755 gitweb/gitweb.cgi %{buildroot}%{_localstatedir}/www/git/
%{__install} -p -m0755 gitweb/gitweb.perl %{buildroot}%{_localstatedir}/www/git/
%{__cp} -av gitweb/static/* %{buildroot}%{_localstatedir}/www/git/static/
%{__install} -Dp -m0644 gitweb/gitweb.httpd %{buildroot}%{_sysconfdir}/httpd/conf.d/git.conf
%{__install} -Dp -m0644 gitweb.conf %{buildroot}%{_sysconfdir}/gitweb.conf

### git-daemon installation
%{__install} -d -m0755 %{buildroot}%{_localstatedir}/lib/git/
%{__install} -d -m0755 %{buildroot}%{_sysconfdir}/xinetd.d/
%{__install} -Dp -m0644 git.xinetd %{buildroot}%{_sysconfdir}/xinetd.d/git

### contrib installation
%{__install} -Dp -m0644 contrib/completion/git-completion.bash %{buildroot}%{_sysconfdir}/bash_completion.d/git

# Move contrib/hooks out of %%docdir and make them executable
%{__install} -d -m0755 %{buildroot}%{_datadir}/git-core/contrib/
%{__mv} -v contrib/hooks %{buildroot}%{_datadir}/git-core/contrib
chmod +x %{buildroot}%{_datadir}/git-core/contrib/hooks/*
pushd contrib > /dev/null
ln -s ../../../git-core/contrib/hooks
popd > /dev/null

desktop-file-install \
    --vendor %{desktop_vendor} \
    --dir=%{buildroot}%{_datadir}/applications \
    git-gui.desktop

### Quiet some rpmlint complaints
chmod -R g-w %{buildroot}
find %{buildroot} -name git-mergetool--lib | xargs chmod a-x
rm -f {Documentation/technical,contrib/emacs}/.gitignore
chmod a-x Documentation/technical/api-index.sh
find contrib -type f | xargs chmod -x

### Clean up buildroot
find %{buildroot}%{_bindir} -type f -exec %{__perl} -pi -e 's|^%{buildroot}||' {} \;
%{__rm} -rf %{buildroot}%{perl_archlib} %{buildroot}%{perl_vendorarch} %{buildroot}%{_datadir}/locale/*

%clean
%{__rm} -rf %{buildroot}

%files
%defattr(-, root, root, 0755)
%doc COPYING Documentation/*.txt README
%doc %{_mandir}/man1/*.1*
%doc %{_mandir}/man5/*.5*
%doc %{_mandir}/man7/*.7*
%config %{_sysconfdir}/bash_completion.d/
%{_datadir}/emacs/site-lisp/git*
%{_bindir}/git
%{_bindir}/git-*
%{_datadir}/git-core/
%{_libexecdir}/git-core/
%exclude %{_libexecdir}/git-core/git-citool
%exclude %{_libexecdir}/git-core/git-cvsexportcommit
%exclude %{_libexecdir}/git-core/git-cvsimport
%exclude %{_libexecdir}/git-core/git-cvsserver
%exclude %{_libexecdir}/git-core/git-daemon
%exclude %{_libexecdir}/git-core/git-gui
%exclude %{_libexecdir}/git-core/git-gui--askpass
%exclude %{_libexecdir}/git-core/git-send-email
%exclude %{_libexecdir}/git-core/git-svn

%files all
%defattr(-, root, root, 0755)

%files arch
%defattr(-, root, root, 0755)
%{_libexecdir}/git-core/git-archimport

%files cvs
%defattr(-, root, root, 0755)
%{_bindir}/git-cvsserver
%{_libexecdir}/git-core/git-cvsexportcommit
%{_libexecdir}/git-core/git-cvsimport
%{_libexecdir}/git-core/git-cvsserver

%files daemon
%defattr(-, root, root, 0755)
%doc Documentation/*daemon*.txt
%config(noreplace)%{_sysconfdir}/xinetd.d/git
%{_libexecdir}/git-core/git-daemon
%{_localstatedir}/lib/git/

%files email
%defattr(-, root, root, 0755)
%{_libexecdir}/git-core/git-send-email

%files gui
%defattr(-, root, root, 0755)
%{_datadir}/applications/%{desktop_vendor}-git-gui.desktop
%{_datadir}/git-gui/
%{_libexecdir}/git-core/git-citool
%{_libexecdir}/git-core/git-gui
%{_libexecdir}/git-core/git-gui--askpass

%files svn
%defattr(-, root, root, 0755)
%{_libexecdir}/git-core/git-svn

%files -n gitk
%defattr(-,root,root)
%doc Documentation/*gitk*.txt
%{_bindir}/gitk
%{_datadir}/gitk/

%files -n gitweb
%defattr(-, root, root, 0755)
%doc gitweb/GITWEB-BUILD-OPTIONS gitweb/INSTALL gitweb/README
%config(noreplace) %{_sysconfdir}/gitweb.conf
%config(noreplace) %{_sysconfdir}/httpd/conf.d/git.conf
%{_datadir}/gitweb/
%{_localstatedir}/www/git/*.cgi
%{_localstatedir}/www/git/*.perl
%{_localstatedir}/www/git/static/*.css
%{_localstatedir}/www/git/static/*.png
%{_localstatedir}/www/git/static/*.js
%{_localstatedir}/www/git/static/js/**

%files -n perl-Git
%defattr(-, root, root, 0755)
%doc %{_mandir}/man3/Git.3pm*
%doc %{_mandir}/man3/Git::I18N.3pm*
%doc %{_mandir}/man3/Git::SVN::Editor.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Fetcher.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Memoize::YAML.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Prompt.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Ra.3pm.gz
# perlモジュールのインストールでエラーが出るので個別にパッケージするファイルを指定
/usr/share/perl5/Git.pm
/usr/share/perl5/Git/I18N.pm
/usr/share/perl5/Git/SVN/Editor.pm
/usr/share/perl5/Git/SVN/Fetcher.pm
/usr/share/perl5/Git/SVN/Memoize/YAML.pm
/usr/share/perl5/Git/SVN/Prompt.pm
/usr/share/perl5/Git/SVN/Ra.pm
# git-1.8.1.1で追加になったモジュール
%doc %{_mandir}/man3/Git::SVN::Utils.3pm.gz
/usr/share/perl5/Git/IndexInfo.pm
/usr/share/perl5/Git/SVN.pm
/usr/share/perl5/Git/SVN/GlobSpec.pm
/usr/share/perl5/Git/SVN/Log.pm
/usr/share/perl5/Git/SVN/Migration.pm
/usr/share/perl5/Git/SVN/Utils.pm


gitweb.conf.in
# The gitweb config file is a fragment of perl code. You can set variables
# using "our $variable = value"; text from "#" character until the end of a
# line is ignored. See perlsyn(1) man page for details.
#
# See /usr/share/doc/gitweb-*/README and /usr/share/doc/gitweb-*/INSTALL for
# more details and available configuration variables.

# Set the path to git projects.  This is an absolute filesystem path which will
# be prepended to the project path.
#our $projectroot = "@PROJECTROOT@";

# Set the list of git base URLs used for URL to where fetch project from, i.e.
# the full URL is "$git_base_url/$project". By default this is empty
#our @git_base_url_list = qw(git://git.example.com
#                            ssh://git.example.com@PROJECTROOT@);

# Enable the 'blame' blob view, showing the last commit that modified
# each line in the file. This can be very CPU-intensive. Disabled by default
#$feature{'blame'}{'default'} = [1];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.blame = 0|1;
#$feature{'blame'}{'override'} = 1;

# Disable the 'snapshot' link, providing a compressed archive of any tree. This
# can potentially generate high traffic if you have large project. Enabled for
# .tar.gz snapshots by default.
#
# Value is a list of formats defined in %known_snapshot_formats that you wish
# to offer.
#$feature{'snapshot'}{'default'} = [];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.snapshot = tbz2,zip; (use "none" to disable)
#$feature{'snapshot'}{'override'} = 1;

# Disable grep search, which will list the files in currently selected tree
# containing the given string. This can be potentially CPU-intensive, of
# course. Enabled by default.
#$feature{'grep'}{'default'} = [0];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.grep = 0|1;
#$feature{'grep'}{'override'} = 1;

# Disable the pickaxe search, which will list the commits that modified a given
# string in a file. This can be practical and quite faster alternative to
# 'blame', but still potentially CPU-intensive. Enabled by default.
#$feature{'pickaxe'}{'default'} = [0];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.pickaxe = 0|1;
#$feature{'pickaxe'}{'override'} = 1;


他にもなんか色々あったかもしれないけど、こんなところかね。
※GCCとか暗黙的に使うようなものは、書いてません。

2013-01-21

[Ruby]Rubyのチートコード(リスト編)

書いてみた。
流行りはRSpecだけど、最近購入してみたRubyMineの設定を煮詰めたり、使いやすさとかを確認してみたかったからminitestでコードを書いた。

ついでにGroovyでも同じコードを書いてみた。
class CheatCode < Test::Unit::TestCase

  # 各テストメソッドが呼ばれる前に実行する前処理
  def setup
  end

  # 各テストメソッドが呼ばれた後に実行する後処理
  def teardown
  end

=begin
配列の初期化
初期要素を代入して初期化する
=end
  def test_array_initial
    ll = [11,12,13,14]
    expected = [11,12,13,14]
    assert_equal(expected,ll,"ll => [11, 12, 15, 13, 14] ")
  end

=begin
配列の初期化
Array.newを使用して初期化する
=end
  def test_array_initial_2
    ll = Array.new([11,12,13,14])
    expected = [11,12,13,14]
    assert_equal(expected,ll,"ll => [11, 12, 13, 14] ")
  end

=begin
配列の要素数を指定して初期化
=end
  def test_array_initial_3
    ll = Array.new(4)
    ll[0] = 11
    ll[1] = 12
    ll[2] = 13
    ll[3] = 14
    expected = [11,12,13,14]
    assert_equal(expected,ll,"ll => [11, 12, 13, 14] ")
  end

=begin
長さ3で各要素を[11,12,13,14]で初期化した配列を生成する
=end
  def test_array_initial_4
    ll = Array.new(3,[11,12,13,14])
    expected = [[11,12,13,14], [11,12,13,14], [11,12,13,14]]
    assert_equal(expected,ll,"ll => [[11,12,13,14], [11,12,13,14], [11,12,13,14]]")
  end

=begin
for-each文
valueは配列の要素を順番に取り出す
=end
  def test_each
    ll = [11,12,13,14]
    expected_1 = 12
    expected_2 = [11,12,13,14]
    # あまりよくないテスト
    # valueが12の時にアサーションを実施
    ll.each do |value|
      if(value == 12)
        assert_equal(expected_1,value,"Value is 12")
      end
    end
    # for-eachを実施しても配列に変化無しであることを確認する
    assert_equal(expected_2,ll,"ll => [11,12,13,14]")
  end

=begin
引数の値が配列かどうかを調べる
配列以外を設定するとnilが返ってくるので、nilではないことでチェックができる
=end
  def test_try_convert
    expected = [11,12,13,14]
    assert_equal(expected,Array.try_convert([11,12,13,14]),"Array.try_convert([11,12,13,14]) => [11,12,13,14]")
    assert_nil(Array.try_convert("11"),"Array.try_convert(\"11\") => nil")
  end


=begin
配列の平滑化をする
配列がネストしているので平滑化された値が取得できる
配列がネストしていない場合は何も実施されない
=end
  def test_add_array_flaten
    ll = [11,12,13,14,[15,16]]
    expected = [11,12,13,14,15,16]
    array = ll.flatten
    assert_equal(expected,array,"ll => [11, 12, 13, 14, 15, 16]")
    assert_equal(expected,array.flatten,"array => [11,12,13,14,15,16]")
  end

=begin
要素の平滑化をする
破壊的な平滑化をする
=end
  def test_add_array_break_flaten
    ll = [11,12,13,14,[15,16]]
    expected = [11,12,13,14,15,16]
    assert_equal(expected,ll.flatten!,"ll.flatten? => [11, 12, 13, 14, 15, 16]")
  end

=begin
要素の平滑化をする
破壊的な平滑化ですでに平滑化済みの場合、nilが返る
=end
  def test_add_array_break_flaten_2
    ll = [11,12,13,14,15,16]
    assert_nil(ll.flatten!,"ll.flatten? => nil")
  end

=begin
配列の末尾を取得する
popメソッドと違って末尾の要素は変更されない
取得要素数を指定した場合、指定した要素数分末尾から取得する
要素数が配列の長さよりも大きい場合は全要素を取得する
配列要素が空の場合、nilを返す
=end
  def test_last
    ll = [11,12,13,14]
    expected_1 = 14
    expected_2 = [13,14]
    expected_3 = [11,12,13,14]
    assert_equal(expected_1,ll.last,"ll.last => 14 / ll => [11,12,13,14]")
    assert_equal(expected_1,ll.last,"ll.last => 14 / ll => [11,12,13,14]")
    assert_equal(expected_1,ll[-1],"ll[-1] => 14")
    assert_equal(expected_2,ll.last(2),"ll.last(2) => [13,14]")
    assert_equal(expected_3,ll.last(5),"ll.last(2) => [11,12,13,14]")
    ll.clear
    assert_nil(ll.last,"ll.last => nil / ll => []")
  end

=begin
配列を初期化する
===========Groovy===========
def ll = [11,12,13,14]
ll = []
assert ll.size() == 0
============================
=end
  def test_list_clear
    ll = [11,12,13,14]
    expected = true
    ll.clear
    assert_equal(expected,ll.empty?,"ll.empty? is true / ll => []")
  end



=begin
引数に指定した要素と等しい要素のうち最初の位置を取得する
===========Groovy===========
def ll = [11,12,13,14]
assert ll.findIndexOf  { it > 12 } == 2
============================
=end
  def test_index
    ll = [11,12,13,14,12]
    expected_1 = 1
    expected_2 = 2
    assert_equal(expected_1,ll.index(12),"first Value is 1")
    # 条件を指定(12よりも大きい要素)
    assert_equal(expected_2,ll.index{ |value| value > 12 },"first Value is 2")
  end

=begin
リストから条件にあった要素の数を取得する
countメソッドは要素を「==」で判定する
===========Groovy===========
List ll = [11,12,13,14,13]
assert ll.count(13) == 2
assert ll.count {it % 2 == 0 } == 2
============================
=end
  def test_grep_count
    ll = [11,12,13,14,13]
    expected = 2
    assert_equal(expected,ll.count(13),"ll.count(13) => 2")
    assert_equal(expected,ll.count{|item| item%2==0},"ll.count{|item| item%2==0} => 2")
  end

=begin
リストから条件にあったもののリストを取得する
===========Groovy===========
List ll = [11,12,13,14]
assert ll.grep {it % 2 == 0 } == [12,14]
============================
=end
  def test_grep
    ll = [11,12,13,14]
    expected = [12,14]
    assert_equal(expected,ll.select{|item| item%2==0},"ll.select{|item| item%2==0} => [12,14]")
  end

=begin
リストの末尾に要素を追加する
以下のようにすることもできる
・「ll << 15」のように破壊的に追加
・「ll.push 15,16」のように連続して要素を末尾に追加
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,13,14,15]
ll.add(15)
assert ll == expected
============================
=end
def test_add_data
  ll = [11,12,13,14]
  expected = [11,12,13,14,15]
  ll.push 15
  assert_equal(expected,ll,"ll => [11,12,13,14,15]")
end

=begin
要素の装入する位置をして、リストに要素を追加する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,15,13,14]
ll.add(2,15)
assert ll == expected
============================
=end
  def test_add_selected_index
    ll = [11,12,13,14]
    expected = [11,12,15,13,14]
    ll[2,0] = 15
    assert_equal(expected,ll,"ll => [11, 12, 15, 13, 14] ")
  end

=begin
リストから添字の位置に含まれる要素を取得する
リストの範囲外を指定した場合、nilを取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = 12
assert ll.get(1) == expected
assert ll[1] == expected
※リストの範囲外を指定するとIndexOutOfBoundsExceptionが発生する
============================
=end
  def test_get
    ll = [11,12,13,14]
    expected = 12
    assert_equal(expected,ll[1],"ll[1] => 12")
    assert_equal(expected,ll.at(1),"ll.at(1) => 12.")
    assert_nil(ll.at(5),"ll.at(nil) => 12.")
  end

=begin
リストが空であるかどうか調べる
空の場合、trueとなる
===========Groovy===========
def ll = [11,12,13,14]
assert ll.isEmpty() == false
============================
=end
  def test_list_empty
    ll = [11,12,13,14]
    expected = false
    assert_equal(expected,ll.empty?,"ll.empty? is false / ll => [11,12,13,14]")
  end

=begin
配列要素の数を取得する
配列の要素数に変更があった場合、要素数も変更になる
要素の中に配列が入った場合、配列が1要素として扱われる
===========Groovy===========
def ll = [11,12,13,14]
def expected = 4
assert ll.size() == expected
============================
=end
  def test_size
    ll = [11,12,13,14]
    add = [15,16]

    expected_1 = 4
    expected_2 = 3
    expected_3 = 4
    expected_4 = 0

    assert_equal(expected_1,ll.size,"ll.size is 4")
    assert_equal(expected_1,ll.length,"ll.size is 4")
    ll.pop
    assert_equal(expected_2,ll.size,"ll.size is 3")
    ll.push(add)
    assert_equal(expected_3,ll.size,"ll.size is 4 / ll => [11,12,13,[15,16]")
    ll.clear
    assert_equal(expected_4,ll.size,"ll.size is 4 / ll => []")
  end

=begin
リストから指定した範囲の要素のみのリストを取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [12,13]
assert ll.getAt(1..2) == expected
assert ll.getAt([1,2]) == expected
============================
=end
def test_selected_range
  ll = [11,12,13,14]
  expected_1 = [12,13]
  expected_2 = [12,13,14]
  assert_equal(expected_1,ll.slice(1,2),"ll.slice(1,2) => [12,13]")
  assert_equal(expected_2,ll.slice(1..3),"ll.slice(1..2) => [12,13]")
  assert_nil(ll.slice(5,1),"ll.slice(5,1) => nil")
end

=begin
リストの共通部分を取り出す
===========Groovy===========
def ll = [11,12,13,14]
def common = [12,13]
def expected = [12,13]
assert ll.intersect(common) == expected
============================
=end
def test_common
  ll = [11,12,13,14]
  common = [12,13]
  expected = [12,13]
  assert_equal(expected,ll & common,"ll & common => [12,13]")
end

=begin
配列の末尾を取り出す
===========Groovy===========
    def ll = [11,12,13,14]
    def expected_1 = 14
    def expected_2 = [11,12,13]
    assert ll.pop() == expected_1
    assert ll == expected_2
============================
=end
  def test_pop
    ll = [11,12,13,14]
    expected_1 = 14
    expected_2 = 13
    assert_equal(expected_1,ll.pop,"ll.pop => 14 / ll => [11,12,13]")
    assert_equal(expected_2,ll.pop,"ll.pop => 13 / ll => [11,12]")
  end


=begin
リスト内の要素の並び順を降順に変更したリストを取得する
メソッドの末尾に「!」をつけると自分自身のリストの並び順を変更する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [14,13,12,11]
assert ll.reverse() == expected
============================
=end
def test_reverse
  ll = [11,12,13,14]
  expected_1 = [14,13,12,11]
  expected_2 = [11,12,13,14]
  assert_equal(expected_1,ll.reverse,"ll.reverse => [14,13,12,11]")
  assert_equal(expected_2,ll,"ll => [11,12,13,14]")
  ll.reverse!
  assert_equal(expected_1,ll,"ll => [11,12,13,14]")
end

=begin
リストをソートする
===========Groovy===========
def ll = [12,13,11,14]
def expected = [11,12,13,14]
assert ll.sort() == expected
============================
=end
def test_sort
  ll = [12,13,11,14]
  expected_1 = [11,12,13,14]
  expected_2 = [12,13,11,14]
  assert_equal(expected_1,ll.sort,"ll.sort => [11,12,13,14]")
  assert_equal(expected_2,ll,"ll => [12,13,11,14]")
  ll.sort!
  assert_equal(expected_1,ll,"ll.sort => [11,12,13,14]")
end

=begin
リストの中で最大の値を取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = 14
assert ll.max() == expected
============================
=end
  def test_max
    ll = [11,12,13,14]
    expected = 14
    assert_equal(expected,ll.max,"ll.max is 14")
  end

=begin
リストの中で最小の値を取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = 11
assert ll.min() == expected
============================
=end
  def test_min
    ll = [11,12,13,14]
    expected = 11
    assert_equal(expected,ll.min,"ll.max is 14")
  end


=begin
リストの末尾にリストを追加する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,13,14,[15,16]]
ll.push([15,16])
assert ll == expected
============================
=end
  def test_add_array_last
    ll = [11,12,13,14]
    expected = [11,12,13,14,[15,16]]
    # 追加要素
    add = [15,16]
    ll.push(add)
    assert_equal(expected,ll,"ll =>  [11, 12, 13, 14, [15, 16]]")
  end

=begin
pushメソッドを使用せず、リストの末尾にリストを追加する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,13,14,[15,16]]
ll <<[15,16]
assert ll == expected
============================
=end
  def test_add_array_last_2
    ll = [11,12,13,14]
    expected = [11,12,13,14,[15,16]]
    add = [15,16]
    ll << add
    assert_equal(expected,ll,"ll => [11, 12, 13, 14, [15, 16]]")
  end
end


RubyのほうがGroovyよりも書きやすいや。。。
テストコードを書くときぐらいしか使いそうもないな

2013-01-20

[JavaScript]cloneNodeの動作が違って嵌ったので対処してみた

新年、明けましておめでとうございます。
今年もよろしくお願いします。

って言うの遅すぎというか今更ですねw
昨年末からかなりドタバタで忙しい状況が続きそろそろ収束して欲しいなぁとか思うところ

さて、表題の内容でハマりました・・・

イベント付きの要素をクローンしようとすると、正しく動作しなかった。
正確にはクローンするけれど、イベントも含めたクローンまではできなかった。

因みに、IE8,9は問題なくイベントを含めてクローンできてました
IE8,9はこれでイベントを含めてクローンできている
var clone = document.getElementById('list').cloneNode(true)

調べてみるとどうもIE7の仕様っぽい罠
同一プロセス内でcloneNodeした要素は、複製元のidを参照し続けるっぽい。(別プロセスなら問題ないっぽいけどどうすんだろ・・・)
なので、クローンしても元の要素が参照されっぱなしになる模様(ふざけんなって仕様ですね。)


対処方法
JQueryを使ってcloneを実施する
JQueryを使うことでイベントを含めたコピーがIE7でもできました。
JQueryを使える環境ではない場合の対処方法は思いつきませんでした。
※以下は試してみたけど、うまく動きませんでした(やり方が悪かったのかもしれませんが^^;)
・innerHTMLを使ってコピー元からコピー先に要素を渡してやれば回避できる
・コピー元の要素に含まれている要素をコピー先の要素にコピーしてやれば回避できる

こんな感じにすれば、イベントを含めたクローンがIE7でもできます。
var tmp_dom_list = document.getElementById('list')
var tmp_jq_list = $(tmp_dom_list)
var tmp_jq_clone = $(tmp_jq_list).clone(true)
var clone = tmp_jq_clone[0]

手順は、こんな感じ
1.DOM要素空JQueryオブジェクトに変換
2.イベントを含めたクローン
3.JQueryオブジェクトからDOM要素に変換

ブラウザごとに対応として条件分岐でいれてやれば、ブラウザごとで意図どおりの動きになると思います。

ついでなので、JQueryとDOMの相互変換
▲DOM→jQuery
 $()をつけてあげればよい
 $(document.body)

▲JQuery→DOM
 jQueryオブジェクトの0番目の要素にアクセスすればよい
 
 var obj = $("select[name='test']");
 var val = obj[0]



本当にIE爆発しろ!!

Blogger Syntax Highliter