tmuxでanyenv(*env)で*env/shimsがsystemのPATHより前に読まれてsystemが使われてしまう対処

anyenvを使っているんですが、

/usr/local/heroku/bin
/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/shims
/Users/monmon/.anyenv/bin
/Users/monmon/local/bin
/Users/monmon/bin
/usr/local/sbin
/usr/local/bin
/usr/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin

のようなPATHがtmuxを起動すると

/usr/local/heroku/bin
/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/bin
/Users/monmon/local/bin
/Users/monmon/bin
/usr/local/sbin
/usr/local/bin
/usr/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
/usr/local/heroku/bin
/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/bin
/Users/monmon/local/bin
/Users/monmon/bin
/usr/local/sbin
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/shims

のようになってshimsが

/usr/local/bin
/usr/bin

より前に読まれてしまい、plenvのperlではなくsystemのperlが使われてしまいます(typeset -U path PATHはしてない状態)。


で、自分の環境だけの話なのかなぁと思ったら
http://konboi.hatenablog.com/entry/2013/12/12/213931
みたいなのも見つけて

rbenv works by inserting a directory of shims at the front of your PATH:
~/.rbenv/shims:/usr/local/bin:/usr/bin:/bin


Understanding Shims

ってのも見て「どうしたらいいんだろう?」と中身見てみた。


結果、anyenvだけの話ではないのだけど、~/.anyenv/libexec/anyenv-init内の

102   echo "$(${ENV_ROOT}/bin/${env} init -)"

の所で、初めに実行された時には

export PATH=/Users/monmon/.anyenv/envs/plenv/shims:/Users/monmon/.anyenv/bin:/Users/monmon/local/bin:/Users/monmon/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

なんですが、tmuxを起動した時にもう一度実行された時には

source /Users/monmon/.anyenv/envs/plenv/libexec/../completions/plenv.zsh

になるので、shimsをPATHに入れるタイミングが初めにしかなく、shimsがsystemより前になってしまう。


ということで、結果的に良いか分からないけど、shimsをPATHで読み込むようにしました。

-  ANYENV_ADD_PATH="${ENV_ROOT}/bin:${ANYENV_ADD_PATH}"
+  ANYENV_ADD_PATH="${ENV_ROOT}/bin:${ENV_ROOT}/shims:${ANYENV_ADD_PATH}"

https://github.com/monmon/anyenv/commit/5e976cd66904b8e4771f1aca8ed4b32ab43de80d


こうすることで、tmux使ってない場合には

/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/envs/plenv/shims
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/shims

となってしまって良いのか悪いのかわからないけど、僕はtypeset -U path PATHでPATHの重複消しているのでいいかなと思いました。
これ、anyenvだけの問題ではないと思うのでもっといい解決方法あるんじゃないかなと思ったんだけど探せませんでした。

「Minillaをインストールしようと思ったらテストが通らない!><」と思ったら~/.gitignoreのせいでした

家でサクッとインストールできたはずなのに会社で以下のようなエラーが出て「あれー!」となりました。

===(      49;1  0/?  0/?  1/? )=========================================Use of uninitialized value in string eq at /Users/no-kumagai/.cpanm/work/1386851499.15174/Minilla-v0.11.0/blib/lib/Minilla/ReleaseTest.pm line 49.

        #   Failed test at t/filegatherer.t line 32.
        #          got: '.gitmodules,META.json,README,foo,libfoo/foo.c'
        #     expected: '.dot/dot,.gitignore,.gitmodules,META.json,README,foo,libfoo/foo.c,xtra/.dot,xtra/.dotdir/dot'
        # Looks like you failed 1 test of 1.

    #   Failed test 'include_dotfiles'
    #   at t/filegatherer.t line 33.
Use of uninitialized value in string eq at /Users/no-kumagai/.cpanm/work/1386851499.15174/Minilla-v0.11.0/blib/lib/Minilla/ReleaseTest.pm line 49.
===(      50;2  0/?  0/?  2/? )=========================================    # Looks like you failed 1 test of 3.

#   Failed test 'FileGatherer'
#   at t/filegatherer.t line 45.
# Looks like you failed 1 test of 2.
t/filegatherer.t ................... Dubious, test returned 1 (wstat 256, 0x100)

で、コケた結果見たらわかるとおり.(ドットファイル)でこけてる。
単純に~/.gitignoreに

.*

が入ってたからだけでした(ドットファイルはとりあえず弾いて必要なやつだけ追加できるようにする派です)。

idobata.ioでGeneric HookでFAILUREとかSUCCESSを出す

こんにちはmonmonです。
みんなが大好きグループチャットのIdobata
JenkinsのHookが使えたりして便利ですが、cronとかでも失敗した時の
f:id:lesamoureuses:20131028212008p:plain
や成功した時の
f:id:lesamoureuses:20131028212018p:plain
を出したいなって思ったりしますよね。


ということでGeneric Hookを使って出しましょう。


まず失敗。

<span class="label label-important">FAILURE</span>

こんな感じでlabelとlabel-importantのclassを指定したHTMLをidobataさんに飛ばすだけです。


次に成功。

<span class="label label-success">SUCCESS</span>

こんな感じで今度はlabel-successのclassを指定すれば良いです。


ということで、
f:id:lesamoureuses:20131028213228p:plain
って感じや
f:id:lesamoureuses:20131028212747p:plain
って感じの通知をidobataさんに出すことができます。


簡単ですね!

jQueryの.data(key)はjQuery.parseJSONでparseできないときにobjectを返せないからstringを返すよ

JavaScript部分にサーバ側で動的な値入れるのエスケープ考えないとだし嫌だよねー」
「htmlタグのdata属性使ってhtmlのエスケープだけ考えればいいようにしたいよねー」
とか思って

<html data-name="monmon">

みたいなことよくやります。

で、さらにjQueryなら

<html data-obj='{"name":"monmon"}'>
<script type="text/javascript">
console.log($('html').data('obj'));      // Object {name: "monmon"}
console.log($('html').data('obj').name); // monmon
</script>

という感じでJSON形式で書いて.data(key)使ってオブジェクトで受け取るなんてこともよくやります。

なのですが、「\が入ったときどうなるの?」って質問されてちゃんとドキュメント読んでないことに気づきました。

When the data attribute is an object (starts with '{') or array (starts with '[') then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names. If the value isn't parseable as a JavaScript value, it is left as a string.

.data() | jQuery API Documentation

「validならjQuery.parseJSONでparseしてオブジェクトで返すけど、parseできないなら文字列で返すよー」って話だった。
具体的にはjQueryの.data(key)はobjectを返す場合とstringを返す場合がある - jsdo.it - Share JavaScript, HTML5 and CSSの通り。

結論としては、.data(key)で返って来た値でエラー処理入れればいいですね。

データフレームの列に変数を使ってアクセスするときは[[]]を使う

やりたいことはhogeという列をもったdfrmというデータフレームがあったときにhogeが入ったrow_nameという変数を使ってアクセスしたいというもの。

row_name <- hoge

# TODO: row_nameを使ってdfrm$hogeのようにアクセスするにはどうやって書けばいいの?!


いつも

dfrm$name

というアクセス方法しかやったことがなく「これきっとシンタックスシュガーで何かしら書き方あるんだろうなぁ」と思ってRクックブックをパラパラしたらP.66にあった。

1つの列を選択するには、以下のリスト表現のいずれかを使います。

dfrm[["name"]]

nameという名前の1列を返します。

dfrm$name

構文が異なるだけで上記と同じです。

ということで先の場合には、

dfrm[[row_name]]

でいけました。

YAPC::Asia Tokyo 2013 コアスタッフとしての8ヶ月間を振り返って

今年のYAPC::Asia Tokyoにはコアスタッフとして参加しました。
開催期間中はメインホール担当だったのだけど、前夜祭の準備からバタバタしてしまったのと色んな不安やら心配やらで、YAPC全体把握する余裕が全くなかったです。これはスタッフ4回目で初めてのことだったので「もっとやりようあったんだろうなぁ、力不足だったなぁ」と感じてます。

メインホール担当になった鈴木さん、松本さん、やこさん、加藤さんには色々と助けられました。そしてフォローがあまりできず申し訳なかったです。また、ねこかくさん、じごろうさんには上手く仕切ってもらえてJPA理事の安心感みたいなものを感じました。ありがとうございます。

なのでYAPC開催期間中の話はほぼできず、代わりにコアスタッフになってからYAPC始まるまでの流れを書いて今年のYAPCを終わりたいと思います。


1月。コアスタッフとして参加。

1/30の午後に「YAPC::Asia Tokyo 2013がっつりやりませんか 」というメールが牧さんから来ました。

このメールを見た僕はすぐに

monmonです!やりますやります!
毎年の仕事の大変さを見ているのでその負担が減るならぜひぜひ!

と返信。
このタイミングで今年のコアスタッフになりました。

同様のメールが伊藤さん(@umeyuki)、鳥居さん(@torii704)にも行っていて2人も「やりますよー!」ということで3人が決まり、あとから太田さん(@tb_bot)が参加という感じ。

このときの作業内容は

ちなみに今想定している作業内容は以下のような感じです:
* 会場選定・下見・連絡係
* サイト・システムの構築・運営
* サイドイベントの企画・運営(去年のLT-thonみたいなもの)
* ノベルティ等の企画・発注
* 当日の運営等

という感じでした(今見ると巻き取れなかった仕事いくつかあります)。


2月。キックオフと会場決定。

僕らが入ってからのキックオフの段階で「エンジニアのエンジニアによるエンジニアのためのお祭り」というスローガンはできあがっていて、「企画出しどんどんやるよー」な感じで今年のYAPCはスタートしました。

そして2月は主に会場探し。僕が行ったのは3つ。そのうちの1つが慶応でした。
他2つも良かったけどメインホールの感じといい、イベントホールの感じといい、一番慶応が良かったですね。

f:id:lesamoureuses:20131002075742j:plain
(そのまま何か食べたくなるくらいいい感じでした)


3月。3/19公式サイトオープン。3月末には池邉さんがスピリチュアルトーク快諾。

慶応で行うことは決定ということで、新たに太田さんが参加してのランチミーティングが行われました。

f:id:lesamoureuses:20130306121147j:plain
(ぼくは肉そんなに食べられないのでサラダランチにしました)

このタイミングで「祭りっぽく屋台とか提灯(その他、後々ボツになるネタなど)があるといいよね」という話になり、見積もり取りまくるターン。

裏側ではデザインが決まり、サイトができ始め、スポンサー企業向けのメニューも出来上がった感じ。
941さんから「YAPC::Asiaやるためには今後このくらいの作業があるよー」ってのが送られて来たのもこの頃で、もう既に「うわーやばい。どこまで仕事拾えるんだろ」と不安になったのも覚えてます。


4月。スポンサー回りとPerl5国勢調査の結果を見たり。

f:id:lesamoureuses:20130404132337j:plain
(月初ミーティングのメモ。今見るとホントメモだ…)

表側ではスポンサー回りが始まっていて僕もいくつか同行しました。
「1人でやってもらうかもしれないからね!」と言われてたのでこっそりiPhoneで内容を録音したのは良い思い出(最後の打ち上げで鳥居さんも録音してたってのを聞いた)。
僕はほぼ横で聞いてるだけでしたが、横で聞きながら「941さん牧さんの2人のやり取りはたまに漫才みたいな掛け合いになって良くできてるなぁ」と感じてました。

あとPerl5国勢調査を牧さんが出していたのも5月ですね。今回のYAPCのレガシー話が盛況だったのもこの調査結果見ると納得だなぁと思います。


5月。鳥居さんがガリガリとサーバのissue消化、個人スポンサーの名前の見せ方案却下。

この時期、遅れてたサイトの対応を鳥居さんがガリガリやってました。githubで管理してるのにこの辺の仕事に手出していいか迷っちゃって巻き取れなかったのは心残り。そういうのが今年はところどころであり、つくづくコミュニケーション下手だなぁと自分の欠点を再認識したりもしました。

そして9月頭のギリギリまで僕を悩ました「個人スポンサーに対して何ができるか?個人スポンサーのみなさんの名前出したいよね」の案出しもこの頃から始まってて、この時の案は予算の関係でボツでしたね。ホント夢にも出てくるくらい最後まで悩みのタネでした。

そんな個人スポンサーの募集が始まったのも5月。


6月。見積もり集め、クライアント作ること決定、ボランティアスタッフ募集。

結局ボツになったけどホワイエを使って祭りっぽいことをやるために色んなところに見積もり取ってました。普段そういう用途でレンタルしてない所に「YAPC::Asia Tokyoというものがありまして、サイトはこれです、そしてこれこれこうでこうやって盛り上げて行きたいんです!」みたいなのを業者の人と共有するのはなかなかない経験だったので楽しかったです。
結局イメージ通りにやるのが難しいということになって却下になりましたが最終的にこの時にチェックしてた業者さんに月見セットの三宝借りたのでこの時期に色々見てまわって良かったですね。

サーバ側は鳥居さんがガリガリとissueを消化してて、その流れでスケジュールのAPIを用意してもらったために(ギリギリになっちゃったけどリリースできた)クライアントの開発がほぼ決定になりました。

そしてボランティアスタッフ募集。今年もたくさんの人が集まってくれました。応募の時のコメントがみんな乗り気で読んでいて楽しかったです。ありがとうございます。

この頃に大きくなってたコアスタッフ間の問題としては「コミュニケーションロスが原因の空回り」みたいなやつで、「これきっと今まで牧さんと941さん2人の頃は起こらなかった問題なんだろうな」という「人数が増えて距離が増えたことによる問題」みたいなのを感じてました。人数が増えるといいことばかりではないといういう仕事でよく感じる問題をここでも感じました。


7月。YAPCの宣伝のためにフライヤーを会社中に貼ったり、Perl入学式に行ったり、TDDBCに行ったり。そしてボランティアスタッフも一緒にキックオフ。

4月に弊社の学生たちにフライヤーを配ったんですが、学生以外へのリーチをしていなかったので弊社トイレや喫煙室に貼ったり勉強会に回ったりしてました。

毎年恒例になってきたトイレにYAPCの宣伝。

Perl入学式へ行って「みんな来てね!」の宣伝。

TDD Boot Campへ行って「この場にはRubyの人多いみたいけどRubyPerlの座談会あるから来てね!」の宣伝。

そして7月はボランティアスタッフ交えてのキックオフでした。初めてYAPCのデザイナやってる方と出会って「エンジニアとデザイナの仕事のやり方」みたいな話ができて楽しかったです。もうこんな所でもやっぱり仕事に直結する話ができてYAPCとても有意義。

f:id:lesamoureuses:20130717200529j:plain
(ボランティアスタッフも合流してのキックオフ。恒例の941さんのプレゼン)


8月。最後のチケット告知、iOSクライアント、個人スポンサー盛り上げ案。

1月前がチケット締め切りのため、コアスタッフ総出で最後のチケット告知。
「どういうトークが見たい」というのは去年書いたことだし、そういうのじゃないのがいいよね」と思い、今回初めてのワークショップであるPerl入学式のインタビューにしようと@__papix__ さんに連絡してみたら快諾してくれましてSkypeでワイワイやらさせていただきました

そしてiOSクライアント。元々は僕が作るつもりで後輩に「作りたいんだけど」みたいな話をしたらプロトタイプから最終的に完成版まで作ってくれて、僕がp-rするだけの要因になりました。 @huin さんとデザイン担当してくれたみゆきちゃんにはホントに感謝しております。

一方コアスタッフ間のLINEはところどころ盛り上がりを見せてました。

16:28 monmon フォントかわいい
16:28 Aさん はやっ!
16:28 Bさん Monaco です
16:29 Aさん 「変なコード書いたらファックしちゃうよ!」的なニュアンスですか?
16:30 Bさん ちげーw
16:30 Aさん !?
16:30 monmon w
16:30 Bさん うだうだ言ってないで黙ってコードを書けよハゲ
16:30 Bさん ってかんじらしい
16:30 monmon 声出して笑ってしまった恥ずかしい
16:30 Aさん ファックしちゃダメだろw
16:30 Bさん なるほど。
16:31 monmon 太田さん発言が過激過ぎる
16:31 Aさん 火の玉娘や
16:31 Bさん またひとつ頭が良くなりました。

(コアスタッフ間でのLINEのやり取り)


9月。ギリギリの個人スポンサー盛り上げ案、ギリギリのAndroidアプリ、入籍、YAPC当日

9/2に最後のコアスタッフ定例MTG。
「個人スポンサーの名前を見せるか」はこの前日まで妙案が浮かんでいなかったのだけど、ちょうどその頃渋谷では祭りの準備で提灯が出ていて「個人スポンサーの名前並べるなら提灯がやっぱり一番いいんじゃないか?名入れしたちっちゃい提灯とかないのかな?」と思って予算と時間が合う所いろいろ探しまくった。

f:id:lesamoureuses:20130901150743j:plainf:id:lesamoureuses:20130902131832j:plain
(渋谷の祭、提灯の飾り方ばかり写真に撮ってました)

結果、夜に電話をかけたお店が「明日確定させてくれれば間に合わせますよ」と言ってくれて、9/2の定例MTGで「個人スポンサーの名前、ミニ提灯にしましょう!」と提案、「えー、今からじゃ間に合わんでしょ?しかもどうやって飾るの?足場とか大丈夫なわけ?当日に日曜大工してもいいけど」とか色々言われたものの「当日会場に来てください。俺が本当のミニ提灯の飾り方見せてやりますよ」くらいな山岡ばりの発言をして確定。

ずっと悩みのタネだった個人スポンサーへの表現が解決してホントに安心したの覚えてます。7月8月といい案が全く出なくて「Webで表現する」で決まりそうだった所に941さんから「えー、イマイチよくわからないなぁ。それ何かパッとしないよねぇ」ってツッコミが入り、再度色々考えた結果の流れだったので妥協はできる限りするべきじゃないという良い例になりました。

このミニ提灯を作ってくれたお店とはその後も色々やり取りをしたのでYAPC終了後にメールで「こんな感じでできました!厳しい納期で無理言ってスミマセン!」みたいなことを送ったら

確かに厳しい納期ではありましたが、『何とかする』が
心情なので(^^;

イベントの様子を見せて頂きました。提灯の画像もアップ
されていて嬉しい限りです。

とにかく盛大なイベントが無事に開催された事、ご注文
の提灯がその場に無事に展示された事が何よりです。

と返ってきて「はー、ホントにいいお店だった」と改めて感じました。

さてさて、そんな個人スポンサーのミニ提灯、「足場どうやって作るか?」がちゃんとできたのは当日で、前日までハンズと100円ショップ回って会社で試作品何個か作っては失敗みたいなことやってました。
f:id:lesamoureuses:20131002081115p:plain

一緒に手伝ってくれた弊社の@jewel_x12 さんには

今年ももちろん行くでよ〜と意気込んでたところ、【締め切りました!】YAPC::Asia Tokyo 2013 ボランティアスタッフ募集します! | YAPC::Asia Tokyo 2013の記事がまわってきて、Perl知らなくてもボランティアスタッフもできるんじゃない?と酒の勢いで参加登録した覚えがあります。
YAPC::Asia 2013に参加したです! - ミントフレーバー緑茶

と言っている通り、会社でお酒飲んでる時に「じゃあスタッフ募集しておいて」のノリで参加してもらったのにも関わらず色々手伝ってもらえたので感謝してます。ありがとうありがとう。
最終的には当日何とか形になり、個人スポンサーの方々にも喜んでもらえたので「ミニ提灯やって良かったわー。足場もがんばったわー」と自分を褒めております。

Android版のスケジュールクライアント作るのが決まったのも9月のことで、「miyagawaさんの作ったhtml5版もあるからAndroid版は諦めるか」と思っていたところに同僚の@hi6484 さんが「iOS版作ってるならAndroid版作ってあげるよ」と言ってくれて土日使って開発してくれました。ホントにいい同僚たちに恵まれております。ありがたい。

そしてYAPC当日。
最初にも書いたけどホントてんぱっててあんまり覚えてないです。今回は毎年恒例のノベルティ詰め(zigorouメソッド)にも参加しなかったのでそういう意味では僕の中のYAPC、始まってもない気がします。


最後にまとめ

以前の記事他でも書いてますYAPC::Asia Tokyo 2009の @sartak さんの研修は本当に素晴らしく本当に価値があるもので、そんなYAPCに今回コアスタッフとして参加できたことはとても嬉しいです。
それこそ4年前の自分のようにとてつもない価値を得る参加者の方がいるかもしれないわけで、そう考えたらなるべく良いカンファレンスにして、そういうきっかけができる状態にしたいなぁと思って動いてました。今回は例年よりも企画が多かった分、そういうきっかけのできる幅が広かったと思うので個人的にはとても満足です。

あとは自分の会社を巻き込んで企業スポンサーになったことや、回りの人を巻き込んで色々やったのも今年が初めてだったので楽しかったです。色んな人に助けられました。ありがたいありがたい。
またコアスタッフになったことで会社のチームのメンバーには仕事での調整を色々してもらって迷惑もかけました。なんだかんだで好き勝手やらせてもらったのでこちらも感謝しております。

反省点でいうと、コアスタッフ間でのコミュニケーションロスや仕事内容どこまで踏み込んでいいかわからず躊躇したことが一番大きいです。もっと仕事巻き取れたんじゃないかと反省しているし、自分の力不足を実感しました。941さんと牧さんの仕事の進め方とフォローの回り方やっぱりすごい。2人には4年間フォローしてもらいっぱなしでした。本当にありがとうございました。

そして9/16に入籍予定だったため8月9月は群馬と東京を行ったり来たりしてテンパってる僕を最大限の理解で助けてくれたウチの奥さんには本当に感謝してます。
f:id:lesamoureuses:20131002081256p:plain
(コアスタッフにもLINEでちゃんと共有しました)

ということでYAPC::Asia Tokyo 2013ありがとうございました!!!!

iOSの設定画面にアプリのライセンスを置く

WWDCのアプリが設定画面にライセンスを置いていて「じゃあそうしよう」みたいな話になったので調べた。

Settings.bundleとRoot.plistを用意

まずはSettings.bundleってファイルを作れば良くって、その作り方はググるとすぐ出てくる。
具体的には「New File > Resource > Settings Bundle」でOK。
で、そのBundleのディレクトリの下に以下のような内容のRoot.plistを用意する

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>StringsTable</key>
        <string>Root</string>
        <key>PreferenceSpecifiers</key>
        <array>
                <dict>
                        <key>Type</key>
                        <string>PSChildPaneSpecifier</string>
                        <key>Title</key>
                        <string>License</string>
                        <key>File</key>
                        <string>Acknowledgements</string>
                </dict>
        </array>
</dict>
</plist>

Acknowledgements.plistを作る

上で作ったRoot.plistはAcknowledgements.plistを読むような設定になっている(Acknowledgements)ので、Acknowledgements.plistにライセンスをつらつら書けば良い。

で、例えば既に「Acknowledgement.txt」がResourcesディレクトリにあるとして、
以下のようなscriptをResourcesディレクトリに置いて叩けばAcknowledgements.plistが作れる(「Resourcesディレクトリにscript置くのはどうなの?」という疑問は置いておく)

#!perl
use strict;
use warnings;
use FindBin;

my $input = shift || "$FindBin::Bin/Acknowledgement.txt";
my $output = "$FindBin::Bin/Settings.bundle/Acknowledgements.plist";

open my $rfh, '<', $input or die "cannot open $input: $!";
my $license = do { local $/; <$rfh> };
close $rfh;

my $template = do { local $/; <DATA> };

my $plist = sprintf($template, $license);

open my $wfh, '>', $output or die "cannot open $output: $!";
print {$wfh} $plist;
close $wfh;

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>StringsTable</key>
        <string>Acknowledgements</string>
        <key>PreferenceSpecifiers</key>
        <array>
                <dict>
                        <key>Type</key>
                        <string>PSGroupSpecifier</string>
                        <key>Title</key>
                        <string>%s</string>
                </dict>
        </array>
</dict>
</plist>

実際に「Resources/Settings.bundle/Acknowledgements.plist」が作成されていればOK。