2007-06-15
■ [haskell] WindowsでHSDLを使う方法
参考:
- http://d.hatena.ne.jp/TTSY/20070609#p2
- http://www.flightless-wing.com/index.php?%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%2FHaskell%2FHSDL
セットアップ
- GHC 6.6.xをアンインストールする (ちょw)
- GHC 6.4をインストール
- HSDLを配布ページからダウンロードして解凍
- SDL-devel-1.2.11-VC6.zipをSDLのページからダウンロードして解凍
- HSDL.cabalを以下のような感じで編集
include-dirs: C:/research/HSDL/SDL-1.2.11/include ld-options: -LC:/research/HSDL/SDL-1.2.11/lib
あとは
C:\research\HSDL\HSDL-0.2.0> runhaskell Setup.hs configure C:\research\HSDL\HSDL-0.2.0> runhaskell Setup.hs build C:\research\HSDL\HSDL-0.2.0> runhaskell Setup.hs install
でOK。
テスト
haSDLis(テトリス)をダウンロードして
C:\research\HSDL\haSDLis>ghci main.hs ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.4, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base-1.0 ... linking ... done. Compiling Main ( main.hs, interpreted ) Ok, modules loaded: Main. *Main> main
とするとテトリスが遊べるはずです。
TTSYさんの方法だと、うちではキー入力を受け付けてくれなかったので、 諦めてGHC 6.4を入れてしまいました。
2007-06-13
■ [Ruby/SDL] 「初心者向け」について
ということで、「るびま」で
Ruby/SDLで始めるゲームプログラミング
を見たときには「これだ!」と思ったんですけど、「ウインドウを開く前に変数のなんたるかを知らなければならない」というのは初心者的にはどうなんでしょう(純粋に疑問)。
[http://d.hatena.ne.jp/kmaebashi/20070611より引用]
実を言うとあの記事はもうちょっと初心者向けに書きたかったんですけど、 僕の実力不足で多少Rubyの知識を前提にしています。すいません。*1というのもありつつ。
「Ruby/SDLスターターキット」とMyGameは合体したほうがいいんじゃないかと思うわけですよ。
[http://dgames.jp/dan/?date=20070613#p02より引用]
僕もそうした方が良いような気がしてきましたですよ。- 初心者 → MyGame + スターターキット
- 中級者 → Miyako
- 上級者 → もちろん、フレームワークから自作 :-)
という感じ?
*1 ていうか、本当に初心者向けに書いてたら多分8回連載とかになってたと思われ(笑)
■ [prog] 初心者に特化した言語
あれなんだよな、HSPは初心者に特化した言語だと思うんですよね。 プログラミングに関する前提知識がない人に最適化されてるというか。 僕が触ってた頃(7年くらい前?)はたしか戻り値の概念すら無かったし。
もちろんそれは割り切りであって悪いことではないですが。
Rubyの文法でどこまでその域に迫れるか?ってのも面白いかもな。
■ [softs] タブブラウザfubで蒸発機能が検討されている模様
期待age。
fubはタブをメタタブでグループ化できるブラウザで、さらに終了時に開いてるタブを保存できるので、 使い方によっては開きっぱなしのタブがどんどん増えていく。 だから、これを閉じるなりブクマするなりお気に入りに入れるなりして自分で閉じないといけないんだけど、 自動でなんとかしてくれると嬉しいよね。という話(だと思うけど俺の勘違いかも知れない)。
最後にアクティブにしてから1時間経ったらタブだけ残して中身消しちゃう。
これ欲しい。メモリ消費が少なくなって良さそう。ついでにGMailだけは消さずに置いとくとかできると嬉しい。
2007-06-12
■ [Ruby/SDL][idea] 位置決め
ゲーム製作において、キャラクタや文字の位置を決めるのが結構めんどい。「ちょっと座標をいじって再実行」とかさ。
GUIビルダみたいな感じで位置を検討できると便利そうだ。
■ [Ruby/SDL][idea] デバッガ
スライドに書き忘れたんだけどHSPは実行時に変数の内容とか別ウィンドウに表示できて便利だった覚えがあります。
最近local_variablesというメソッドを知ったので、Rubyでも(黒魔術を駆使すれば)実装できそうな予感。
■ [ruby] あるURLからフィードを見つけてくれるライブラリ、FeedDiscover
例のOPMLを作るときにいちいちフィードのURLを探すのが面倒だったので、rubyforgeからそれっぽい (PerlのFeed::Findみたいな)ライブラリを探してみました。
FeedDiscoverを使うと、あるURLのHTMLを解析してフィードのURLを見つけてくれます。
インストールは gem install feed_discover で。
長所
使い方が超簡単なところ。
require 'rubygems' require 'feed_discover' fd = FeedDiscover.new('http://bbc.co.uk/') fd.feeds #=> ["http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml"] fd.feed #=> feeds[0]といっしょ fd.feeds? #=> !feeds.empty?といっしょ
短所
- 遅い(パーサのせい?)
- たまにフィードを見つけられない
- たまにHTMLがパースできなくて落ちる
Hpricotベースになるといいなぁ。
■ [ruby][memo] eachで回してるときの次の要素がほしい
ary.each do |item| ... end
みたいな定番のループで、itemの次の要素や前の要素が欲しくなることってないかい?
こういう時はだいたい下のようにインデックスを使うようにするんだけど、もっと簡単な方法はないかな。
(0..ary.size).each do |i| prev = item[i-1] succ = item[i+1] end
隣り合う要素を2つずつ…ってことは隙あらばinjectか?
ary.inject([]){|sum, item| ... }
いやいや、injectは「ある要素」と「そこまでの結果」を扱うメソッドだからあんまり向いてないよな。
prevやsuccが暗黙的に束縛されるようなメソッドを(Rubyレベルで)実装できないだろうか。
ary.each_with_prevsucc do |item| p [prev, item, succ] end
(追記:いろいろな解決案が寄せられています。
- http://mono.kmc.gr.jp/~yhara/d/?date=20070612#c01
- http://mono.kmc.gr.jp/~yhara/d/?date=20070612#c02
- http://mono.kmc.gr.jp/~yhara/d/?date=20070612#c03
- http://d.hatena.ne.jp/odz/20070612
- http://shinh.skr.jp/m/?date=20070613#p01
- http://d.hatena.ne.jp/ku-ma-me/20070613/p2
- http://d.hatena.ne.jp/ku-ma-me/20070614/p1
- http://d.hatena.ne.jp/niha/20070613
- http://d.hatena.ne.jp/ha-tan/20070613/1181759059
- http://d.hatena.ne.jp/sumim/20070614/p1
- http://d.hatena.ne.jp/kaitoh/20070614
- http://d.hatena.ne.jp/xtalco/20070616#1181848684
- http://d.hatena.ne.jp/oto-oto-oto/20070119/1169283285#c
ありがとうございます。あとでまとめるかも。)
■ [ruby] SimpleOPML
RubyでOPMLファイルを生成するクラスを作ってみました。
OPMLはもともと文書のアウトラインを記述するフォーマットとして作られた そうなのですが、今ではなぜかRSSのリストを記述するのに使われているようです。
OPMLファイルの仕様に関しては以下のサイトが参考になります。
require 'cgi' require 'time' require 'kconv' require 'rubygems' require 'hpricot' require 'open-uri' class SimpleOPML Site = Struct.new(:url, :rss, :title) def initialize(title) @title = title @sites = [] end def add(url, rss, title=nil) title = get_title(url) if title.nil? @sites << Site.new(url, rss, title) end def get_title(url) doc = Hpricot(open(url).read) if (title = doc % :title) title.inner_html else "" end end def to_s <<EOD <?xml version="1.0" encoding="utf-8"?> <opml version="1.0"> <head> <title>#{CGI.escapeHTML @title}</title> <dateCreated>#{Time.now.rfc822}</dateCreated> <ownerName /> </head> <body> <outline text="Subscriptions"> #{@sites.map{|s| site_to_outline(s)}} </outline> </body> </opml> EOD end def site_to_outline(site) %!<outline title="#{CGI.escapeHTML site.title.toutf8}" htmlUrl="#{CGI.escapeHTML site.url}" text="#{CGI.escapeHTML site.title.toutf8}" type="rss" xmlUrl="#{CGI.escapeHTML site.rss}" />\n! end end #---- example opml = SimpleOPML.new("RubyKaigi2007 Speakers & Staffs") File.read("sites.txt").each do |line| url, feed = line.split /\t/ opml.add(url, feed) end puts opml
2007-06-11
■ [ruby][event] RubyKaigi2007発表者のブログ一覧
日本 Ruby 会議 2007の発表者の方々のブログをまとめてみました。
- (6/13追記:OPMLを作りました。livedoor ReaderなどのRSSリーダに食わすとまとめて登録できます。)
- (6/15追記:version 2になりました。)
一日目
- オープニング (高橋 征義)
- Ruby 1.9実装の現状と今後 (笹田 耕一 ko1)
- 安定版rubyとその今後 (卜部 昌平 mput)
- 日本Rubyのリファレンスマニュアル2007・初夏 (青木 峰郎 aamine)
- JRuby: Ruby for the Java Platform (Charles Nutter / Thomas Enebo)
- 2007年とその先のRuby (まつもと ゆきひろ matz)
- 他言語ライブラリの利用 (立石 孝彰 ttate)
- Cより速いRubyプログラム (桑田 誠 kwatch)*1
- YAR(V)I (Yet Another Ruby (on VM) Implementations) (arton)
- rubyでする Web scrapping - Hpricot と mechanize そして scRubyt (朴 芝印)
- The World In 30 Minutes (Tim Bray)
- Rinda: Answering the RubyConf and RubyKaigi (関 将俊 m_seki)
Lightning Talks
- LT1. 数値データ管理・解析・可視化アプリケーション "Gfdnavi" (西澤 誠也) *2
- LT2. Software is Made of Design and Communication (平鍋 健児)
- LT3. 「Ruby+Miyako」でおもろいプレゼン (サイロス誠)
- LT4. Rubyでファミコンプログラミング (takkaw)
- LT5. Ruby on Railsでデータマイニング (山形 頼之 id:yoriyuki)
- LT6. Rubyのパーサーを拡張して "end" の対応付けをチェックする (山野 ゆき菜)*3
- LT7. マルチコアプロセッサでのRubyプログラムの高速実行方式 (米澤 直記)*4
- LT8. 「地域資源」Rubyと島根県の産業振興の取り組み (野田 哲夫)*5
- LT9. 5分で作るCometチャット (瀧内 元気)
- LT10. データで予想する Ruby のリリース (田中 哲 akr)*6
- LT11. 第2日本Rubyの会について (高橋 征義)
二日目
- もっと仕事で使うRuby (後藤 謙太郎 gotoken)
- JRuby on Rails でエンタープライズ Ruby (高井 直人)
- OpenWFEru, a Ruby workflow engine (John Mettraux)
- AP4R : Ruby のための非同期メッセージングライブラリ (篠原 俊一 id:ita-wasa / 加藤 究 id:kiwamu)
- Inside Ruby/Tk (永井 秀利) *7
- Hello Ruby-GNOME2 World (武藤 昌夫 むとう まさお)
- VisualuRuby計画(仮称)によるWindowsでのGUI開発 (nyasu)
- RubyCocoa - RubyによるMac OS Xソフトウェア開発 (藤本 尚邦 hisa)
- モテる Ruby!Ruby で画像編集のあの手この手 (舘野 祐一 id:secondlife)
- Ruby/SDLとその周辺 (大林 一平 ohai / 原 悠 yhara)
- rcairo (須藤 功平)*8
- 私はいかにRubyでメディア・アート作品をつくり、しかも一円も損をしなかったか (えと こういちろう eto)
- Island Ruby, or How To Survive Invasions, Immigrants, and Cultural Attacks(Dave Thomas)
RejectKaigi
- なぜRject Kaigiが行なわれることになったか勝手に語る (井上 泰之)
- 「ゆきひろ」(not ひろゆき) 認証 (斎藤ただし)
- A Jail development with Rails 2nd edition (竹迫 良範 TAKESAKO)
- MathMLライブラリのご紹介 (黒田 拓)
- オブジェクト指向パーザつくってます。が… (zunda)
- Rel - Ruby (+7NF) (吉田 和弘 moriq)
- Rubyのキャッシュミスをへらす (吉岡 弘隆)
- AgileなRuby教育術 (吉田 裕美 id:yuum3)
- Rubyで作ったゲームデモ (だん dan5)
- fro-grammer (増井 雄一郎 masuidrive)
- My Rspec Best Practice (園田 裕貴 yugui)
- nextとbreakとreturn (田中 哲 akr)
- td2 planet (西山 和広 znz)
- Pragger is LL (松本 宗太郎 soutaro)
- RubycocoaでLimechat (Psychs)
- From Ruby to Java - RoRからEJB3へのポーティング (高井 直人)
- vim (舘野 祐一 id:secondlife)
- High Performance Ruby (ささだ こういち ko1)
- ちょっと私の話を聞いてください (かくたに)
実行委員会
- 高橋征義(日本Rubyの会会長 / 株式会社ツインスパーク)
- 角谷信太郎(日本Rubyの会 || (株)永和システムマネジメント)
- 笹田耕一(日本Rubyの会 / 東京大学大学院情報理工学系研究科創造情報学専攻)
- 重富巧彦(日本Rubyの会)
- のりお(茨城)
- かずひこ(オープンソースプログラマ)
- ただただし(日本Rubyの会)
- 中尾光輝(BioRuby)
- 諸橋恭介((株)永和システムマネジメント/Rails勉強会@東京 裏方)
- 三浦智彦(日本Rubyの会)
- ふしはらかん(日本Rubyの会, 株式会社モバイルファクトリー)
- えとこういちろう(Rubyist, 産総研/東大)
- 荻野淳也(あとで書く)
- 沢田洋平(ニート)
- Zev Blut(TLUG)
- Leonard Chin (日本Rubyの会)
- ながやまん(幹事)
当日スタッフ、ロガー、司会
- たけうち(東京外国語大学)
- 設樂洋爾(dara)
- 島田浩二(snoozer.05)
- 磯辺和彦(株式会社ビジネス・アーキテクツ)
- 柳沢 恵
- 木下史彦((株)永和システムマネジメント)
- だん(日本Rubyの会)
- kitaj(tDiary)
- 斎藤ただし(筑波大学)
- zunda(るびま編集)
- よう(るびま編集)
- すずき みほ (株式会社ツインスパーク)
コメントでいくつかブログを教えていただきました。ありがとうございます。
2007-06-08
■ [ruby] caller_binding
Kernel#local_variables というメソッドがあるだなんて知らなかったよ!(それっぽいのがあるとしたら Binding のメソッドかなあと踏んでそっち探してたよ
[http://yowaken.dip.jp/tdiary/20070608.html#p01より引用]
俺も俺も!あと呼び出し元のbindingを取るのは callcc + set_trace_func でできます(Rails方面ではBinding.of_callerという名前で提供されているらしい)。
■ [web] Re: 「追加して確認」ボタンがなくなった
個人的には「追加して閉じる」ボタンが欲しいです。[あとで読む]でブクマしたあと、手動でウィンドウを閉じるのがめんどい。
2007-06-05
■ [scheme] FizzBuzz一般化 (2)
動くまでに28分、リファクタリングに10分くらい。
「=」が数値の比較であることを忘れててだいぶはまった。(どの関数のエラーメッセージなのかも出してくれると嬉しいなぁ。)
[D:\proj]d:\prog\Gauche\bin\gosh ./fizzbuzzx.scm 1 100 3 Fizz 5 Buzz *** ERROR: real number required: #f Stack Trace: _______________________________________
回答はこんな感じで。
(use util.list) ;slices (use srfi-1) ;iota (define (fizzbuzz from to mapping) ;mapping -> '((3 . "Fizz") (5 . "Buzz") ..) (define (integer->fizzbuzz i) (let1 mapped (map (lambda (pair) (let ((n (car pair)) (str (cdr pair))) (if (= (modulo i n) 0) str ""))) mapping) (if (every (cut string=? <> "") mapped) (number->string i) (apply string-append mapped)))) (map integer->fizzbuzz (iota to from))) (define (main args) (cond ((< (length args) 2) (print "usage: fizzbuzz.scm 1 100 3 Fizz 5 Buzz ...")) (else (let ((from (string->number (cadr args))) (to (string->number (caddr args))) (mapping (map (lambda (ls) (cons (string->number (car ls)) (cadr ls))) (slices (cdddr args) 2)))) (for-each print (fizzbuzz from to mapping))))))
2007-06-04
■ [event][erlang] Erlang勉強会#1
というわけで(どういうわけだ) Erlang勉強会#1 に行ってきた。「参加者はfizzbuzzを書いてくること」という 告知にもかかわらず12人も集まってすげー!と思ったんだけど、 やっぱり半分くらいの人がまだ書けてなかった(笑)。僕ですか?電車の中で頑張って書きましたよ。ええ。
-module(fizzbuzz). -compile(export_all). %これは便利 fizzbuzz(N) when N rem 3 == 0 -> "fizz"; fizzbuzz(N) when N rem 5 == 0 -> "buzz"; fizzbuzz(N) when N rem 15 == 0 -> "fizzbuzz"; fizzbuzz(N) -> integer_to_list(N). run() -> lists:map(fun fizzbuzz/1 , lists:seq(1, 100)). %run2() -> [fizzbuzz(X) || X <- lists:seq(1,100)].
数値を"fizz"とか"buzz"とかに変換する関数を書いて、それを1から100までのリストにmapする方向で実装してみた。
- 定義済みの関数を関数に渡すには fun fizzbuzz/1 のように書く(1は引数の個数)。
- 関数は関数名とarityで区別されるらしい。
最初はlists:seqを知らなくて、iotaという関数を実装してた。
iota(Start, Start) -> [Start]; iota(N, Start) -> iota(N-1, Start) ++ [N].
逆順に作ってreverseするほうが速そうだな。
本編では、練習としてold roman (ローマ数字の簡略版、4をIVじゃなくてIIIIのように書く) を整数に変換する関数を書いた。
-module(roman). -compile(export_all). chr2int($M) -> 1000; % 1文字を整数に変換する。「$M」はC言語の「'M'」、Rubyの「?M」。 chr2int($D) -> 500; chr2int($C) -> 100; chr2int($L) -> 50; chr2int($X) -> 10; chr2int($V) -> 5; chr2int($I) -> 1; chr2int(X) -> erlang:error("invalid char in old roman: " ++ [X]). % ++はリストの連結(format使う方がいいかも)。 old2int(Str) -> Mapped = lists:map(fun chr2int/1, Str), % まず整数のリストに変換して、 Soted = lists:reverse(lists:sort(Mapped)), % ソートしたものを作る if Soted == Mapped -> lists:sum(Mapped); true -> erlang:error("invalid order in old roman: " ++ Str) end.
old romanの仕様から考えると、"VII"はいいけど"IVI"とかはエラーにしたい。ここではまず整数のリストを作って、 それが降順かどうかでエラーチェックするようにしてみた。ソートして同じかを比較するというのはなんきさんの案。 本当は「(apply < ls)」みたいなことがしたかったんだけど(scheme脳)、多引数の「<」みたいな便利なもんはあるのかな。
- erlang:errorでエラーを通知できる。(ここはthrowで例外を投げるほうがいいかも?)
- エラーメッセージは親切にしておかないと、処理系のエラーなのか自前のエラーなのか見分けがつきません(笑) 気をつけよう。
- ifの見た目が変態すぎるw
- ifっていうかcondだよね
- 条件に副作用を持つものは書けない(?)らしい。
その他:
- =:= っていう演算子がある
- ==は、整数と少数を区別しないが、=:= は区別する(1.0 =:= 1は偽)。
- 文字列がなく、数値のリストを作ると文字列と見なされる
1> [104, 111, 103, 101]. "hoge"
- 副作用についてはわりと緩めらしい。HaskellじゃなくてSchemeやOCamlのような。
test() -> io:put_chars("hoge"), io:put_chars("moge"). % 普通にOK
- Emacsのerlang-modeが凄い
- 「;」を打つと、自動的に次の行に関数名を補完してくれたりとか
- 「;」と「.」と「,」を使い分ける→実はエディタ指向言語なのかも
- 例えばC#の仕様はVisual Studioでの補完がやりやすいように考えられてる(という噂)
- HIGHER ORDER PERLという本が熱いらしい
- 目次を見てるだけですでにヤバい(笑)
1558607013
■ [erlang] ESDLが以下略(2)
test\ 以下で
erlc -W -bbeam -I..\.. -I..\include -pa ..\ebin testsprite.erl
とやると、testsprite.beamにコンパイルできる。ってとこまでは分かった。
だがしかし、これを実行しようとすると…
C:\research\Erlang\esdl-0.96.0626\test>erl -pa ..\ebin testsprite.beam Eshell V5.5.4 (abort with ^G) 1> testsprite:go(). Driver Failed {error,driver_incorrect_version} =ERROR REPORT==== 2-Jun-2007::20:23:09 === Error in process <0.29.0> with exit value: {einval,[{erlang,open_port,[{spawn,"s dl_driver"},[binary]]},{sdl,init,1},{testsprite,go,1},{erl_eval,do_apply,5},{she ll,exprs,6},{shell,eval_loop,3}]} ** exited: {einval,[{erlang,open_port,[{spawn,"sdl_driver"},[binary]]}, {sdl,init,1}, {testsprite,go,1}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} **
driver_incorrect_versionって何だよー。
って、driver_incorrect_versionで検索したら自分の日記がでてきた。進歩してねえじゃん。
もうちょっと調べてみる。
■ [ruby][prog] 英語なまりのRuby
Enumerableを操作するのに
@stooges.select {|s| s.name == 'Mo'}
と書く代わりに
@stooges.that.have.name == 'Mo'
と書くためのライブラリ、ho_enumerable.rbについて。
[http://www.rubyist.net/~matz/20070530.html#p04より引用]
一瞬「かっこえー!」と言いそうになったんだけど、プログラミング言語として考えるとこれはセンスないよな。 なんつーか、thatとかhaveが何を返すのかが全然わからんところが嫌だ。せめて
@stooges.that_have.name == 'Mo'
と分けてほしい。
どちらにせよ、自然言語に近くてもプログラミング言語的に不自然だったら駄目だと思う。*1
余談
Lispだと「.」が要らないので、より英語に近くできるらしい。
(例) Loopマクロより:
(loop for x being the hash-keys in ht collect x)
*1 チャレンジとしては面白いけど
■ [ruby] FizzBuzz一般化
14分。
仕様を読み間違えた(optparse使おうとした)のとto_i忘れでちょっとはまった("1".."100" が普通に通るんだよな…)。
require 'enumerator' class FizzBuzz def initialize(argv) raise ArgumentError if argv.size < 2 @start = argv[0].to_i @end = argv[1].to_i @str_mod = [] if argv.size > 2 argv[2..-1].each_slice(2) do |n, str| @str_mod << [n.to_i, str] end end end def run puts (@start..@end).map{|i| s = "" @str_mod.each do |n, str| if i % n == 0 s << str end end s += i.to_s if s.empty? s } end end FizzBuzz.new(ARGV).run
2007-05-30
■ [idea] 動作コンビネータ
関数型らしいゲームプログラミングってないかなぁという話について。
パーサコンビネータみたいに「動作」をつなげて記述するというアプローチはどうだろうか。
move_square = move_right 10 <+> move_down 10 <+> move_left 10 <+> move_top
■ [prog] コーディングって呼ばないで
コーディングってプログラミングのかっこいい言い方だと思ってました。
2007-05-29
■ [softs] Firefoxの許せないところ
- about="_blank" が新規ウィンドウで開く。お前はそれでもタブブラウザか。
- C-hで履歴が開く。いやWindows版は仕方ないとしても、せめてLinux版はBackspaceとして振舞ってくれよ。
いやまあTab Mix Plusを入れればいいんですけど、 「新規ウィンドウを開かない」くらいデフォルトでできてほしい。
■ [ruby] それany?で
link_exist = (doc/:a).any?{|a| a[:href] == 'http://example.com:3000'}
最初「それfindで」というタイトルにしてて、書いてる途中でany?のことを思い出したのは秘密。
あとEnumerable any?で検索するとるりまが一番上に 来ますね。リプレースはすでに始まっているのだ。
■ [Ruby/SDL] 等幅フォントじゃないと点数表示がぐらぐらして鬱陶しいんじゃね?という指摘
http://blawat2015.no-ip.com/~mieki256/diary/200705274.html#200705274S1
その発想はなかった!確かにそうだなぁ。
「"」の分割問題については、ご指摘の通り「ひとつ多かったら " が分かれているものと見なす」という方針にしました。 というか、頑張ってアルゴリズムを考えるよりも、簡単に確認を行えるようにしておいて人間に判断してもらうというアプローチの方が良さそうです。
1文字ずつ画像を作るのは面倒だから駄目です(笑)。いや、そういう仕様にしても 人によっては使ってくれると思うんだけど、それはその人の時間を無駄に消費させている気がしてやだ。
とか書いてる暇があったらリリースしないと…。[たぶん明日やる]
■ [ruby] いまさらFizzBuzz
puts (1..99).map{|i| fizzbuzz = (i%3==0 ? "Fizz" : "") + (i%5==0 ? "Buzz" : "") fizzbuzz.empty? ? i.to_s : fizzbuzz }
面接で「学生時代に力を入れたことは何ですか」だの聞かれるより、FizzBuzzのコードを書かされる方が100万倍いい。
■ [prog] 関数型プログラマはプログラムを木だと思ってるらしい
gauche.nightで出た話題だけど、関数型プログラマはプログラムを木だと思ってるらしい。
(car (string-split (string-reverse (string-upcase str)) "\n"))
うん、これは木だ。
head $ lines $ reverse $ upcase str
Haskellだと $ があるから見た目はネストしてないけど、実際には関数に関数の返り値を渡している。
そう、関数型プログラマは関数呼び出しの中に関数を書くことに抵抗がない。でもC言語とかだとさ、 関数呼び出しの中に関数って書かないじゃん、普通。すごく短いやつを除けば、だいたい一旦変数に代入するでしょ。
そのへんの違いが関数型言語を学ぶときの抵抗になってるのかなぁと思った。
そういう目で見れば、Rubyのメソッドチェーンは 「木構造を使わずに関数的な処理を書くための発明」っていう風に見えてきませんか?
str.upcase.reverse.to_a.first
■ [befunge] befunge-wiki
これはやべぇwwwwwwwwwwwwwww思わずbefungeカテゴリを新設した。
ていうかBefungeで書かれた実用的なアプリケーションという意味では世界初だったりしないすかね?
■ [net] 自宅サーバの台数
えーと、その母集合だと明らかに平均は1未満かと(笑)。
ていうか、自宅サーバを2台以上持つっていう発想が無かったよ。 KMCでも何人かサーバ立ててるけど、みんな1台だと思う。
ちなみにうちのサーバはMac miniですけどまだ何も動かしてないし外から見えません(それを人はサーバと呼ばない)。
■ [net] LDR
登録フィード数: 497件
あと3つで500。っていうかさっき4件ほど追加したからもう500超えたか。
僕はPCかMP3プレーヤーでしか音楽を聴かないので、聴きたかったCDがCCCDだと非常にがっかりする。 CCCDで発売するっていうのは、僕にとっては発売しないのと同じだ。
…っていうのと同じで、SubscribeしようとしたブログがRSSを出力してないとがっかりするようになりつつある(はいはいそれPlaそれPla)
■ [scheme] 熟練したScheme使いは再帰を書かない
いや書かないは嘘だけど、リストを扱う関数が充実してるので自分で再帰してどうこう…っていうのは あまりしなくていいことが最近分かってきた。例えばfoldとか。
あとGaucheには何をするにも低水準(高パフォーマンス)と高水準(使いやすい)のAPIが用意してあって、 「LispはもうひとつのC」を連想した。
■ [ruby] 継続についての記事を書こうと思って早3ヶ月
人はこれを[あとで書かない]と呼ぶ。
じゃなくて、えーと、YARVに継続が入った記念に概略だけ書くと
- 継続は「プログラムの残りの部分」のこと。
- すごく直感的に言うと、RPGにおけるセーブポイントみたいなのを想像するといい。宿屋の主人に話しかけると「現在の状態」をセーブできる。ダンジョンを探索中に「ロード」すると、セーブした瞬間からゲームをやり直せる。
- 継続ってSchemeとかRubyでしか使えないんでしょ?
- →これは誤解。「プログラムの残りの部分」なんだから、「プログラムあるところに継続あり」。
バトー、忘れないで。あなたがプログラムを書くとき、継続は必ずあなたの側にいる。
[http://tsukimi.agusa.i.is.nagoya-u.ac.jp/~sydney/ocaml/index.php?%B7%D1%C2%B3より引用]
- じゃあSchemeやRubyは何が違うのよ?
- →call/ccがあるのが違う。これはcall-with-current-continuationの略で、RPGで例えると どこでもセーブできる みたいなもん。宿屋でもダンジョンでも戦闘中でも。
- call/ccを呼ぶと、「call/ccを呼んだ瞬間」をセーブした継続オブジェクトがもらえる。この継続オブジェクトを実行すると、セーブしたところからプログラムが再開される。
- call/ccがあると何ができるんでしょうか
- 関数的setjmpというか、λ計算的gotoというかなんというか
- 実行順序を好きなように蹂躙できる。メソッドを超えてジャンプできる点でgotoより遙かに凶悪。諸刃の剣。
- 代表的な使い方としては、「プログラムをちょっとだけ止めてあとで再開する」ってのがある。
- ザ・ワールド
- Rubyのyieldが自前で実装できる。とか。
- 「継続渡し」っていうのはcall/ccと関係ある?
- ありません。別物です
- 任意の再帰関数は「プログラムの残りの計算」を引数にとるように書き換えることで末尾再帰にできる。という定理があって、この書き換えがCPS変換と呼ばれています*1。CPSは「Continuation Passing Style(継続渡し形式)」の略ね。
- 継続のRubyでの利用例
- 時を止めるやつ
- コルーチン (ゲームのイベント部分の記述に使ったことあり。効果大。)
- Webアプリ
- 実行順序を操作するやつ
- ppp
- yuguiさんのやつ (これってtransactionをネストして呼び出すのでは駄目なんかな)
- 既存の CGI をそのまま FastCGI 対応に
- SICPのamb (いやRubyじゃないけど、oxy君が書いてたような)
- 時を止めるやつ
継続の弱点はやっぱり慣れないと非常に読みにくいっていう点だと思う。変数名を工夫するとかメソッドにラップするとかしないとな。
あと継続を理解するにはjsSchemeのソースを追っかけるのが良かった。内部構造を見れば、「ああこれが継続か」って思うよ。たぶん。
*1 合ってます?
□ ohai [そういうときは zip かな]
□ nov [そこで Enumerable::Enumerator#{each|enum}_cons ですよ! >> (0..9)..]
□ takkanm [なんとなく誰も言ってないのは、理由があるのかわかりませんが、each_with_indexで十分じゃないかと思ってお..]