Rubyの最近のブログ記事

Clojure をもう少し書けるようになりたいな、と思って Ruby で書いていた CodeEval の課題の幾つかを Clojure で書きなおしてみたんだけど、実行速度が Ruby と比較するととても遅い。。。

例えば Open ChallengesLowercase だと、

  • Ruby : 187 ms
  • Clojure : 5052 ms

27倍くらい時間が掛かっているし、メモリ量も

  • Ruby 3.4MB
  • Clojure 58.1MB

と17倍くらいの開きが。。。
別にランキング入りを狙っているわけではないので、アホみたいに高速で動くコードを書きたいというわけではないですが、初学者として「俺の書いているコード、これじゃ全然ダメなんじゃないか?」と、かなり不安に思っています。

スクリーンショットも貼っておきます。

Screen Shot 2013-11-22 at 10.24.44 AM.png

Ruby 版のコードはこんな感じ。

file = open(ARGV[0])
file.each {|line| print line.downcase! }
file.close

Clojure 版はこんな感じ。

(println (.toLowerCase (slurp (first *command-line-args*))))

「CodeEval で実行するの場合、こう書いた方が早いよ!」というのをご存知の方がいらっしゃいましたら、是非教えて下さい。よろしくお願いします。

おいしいClojure入門 (Software Design plus)
ニコラ・モドリック 安部 重成
技術評論社
売り上げランキング: 57,899

プログラミングClojure 第2版
Stuart Halloway and Aaron Bedra
オーム社
売り上げランキング: 134,200

プログラミング言語 Ruby
まつもと ゆきひろ David Flanagan
オライリージャパン
売り上げランキング: 197,492

言語の世界

  • 松本さん

  • マニアックな話ばかりするので、明日の仕事には役に立ちません。他のセッション出たほうが役に立つと思いますw

  • Rubyを作ったけど、言語好きです

プログラミング言語って

  • プログラム = 手順書
  • プログラミング言語 = 手順書記述用人工言語
    • コンピューターは道具、何かコンピュータで達成したいことがある
    • コンピュータに達成させたいことを記述するもの
    • 自分の理想はなにか、思考の表現をするため、具体化された思考を記述するための実行言語
  • せめぎあうふたつの立場
    • 機械のためか、人のためか、という立場がせめぎ合う

プログラミング言語の歴史的な話

  • FORTRAN
    • FORmula TRANslator
    • 1954年に登場した、世界最初のプログラミング言語
    • アセンブラも存在していなくて、マシン語をそのまま書くような時代に登場したので、画期的だった
    • 「コンピューターのためではなく、人間が楽をするために」
    • 背景:コンピュータが遅かった
      • 1985年のスーパーコンピューターとiPhone4の処理能力がだいたい同じ
    • フォートランの頃は「言語の常識」がなかった
  • LISP
    • LISt Processor
    • 人間のために始まったもの。機械の都合ではない、という点でFORTRANとは対照的
    • ラムダ計算モデルを表現するために作られたものを、そのままコンピュータで動かせば動くんじゃね?って動かしたら動いた
    • IBM704計算機
      • car : content of address registerr
      • cdr : content fo data register
    • ガーベージコレクタ
      • 実装されていた。一般的になるのはJavaの登場によって
  • FORTRANとLISPでバトルしてたら、最終的にAlgolが勝った
    • Algol -> PL/1 とか Pascal とか
    • みなさんが使っている C, C++, Java あたりは Algol 属
  • Lisp へのゆり戻し
    • Smalltalk、Ruby
  • プログラミング言語におけるカンブリア爆発
    • 1960年代~1970年代前半くらい、多種多様な言語が乱立する時代。アイディアなどが次々登場していた時代が
      • C : 1972年
      • Simula : 1967年
      • Shell : 1971年
    • 変な言語も
      • Prolog, APL, アクターモデル
    • 2002年、はRubyもJSもJavaもあった。この10年くらいプログラミング言語は大きな変化はなかった
    • 1960年代~1970年代に生み出されたアイディアを食いつぶしているような状態
      • 「どうせ既存のものの組み合わせさ」
  • 人気の言語はそれなりに新しい。ここ数年で新しいものはあまりないけど
    • Java : 1995年
    • C# : 2000年
    • Scala : 2003年
    • Erlang : 1986年
    • Ruby : 1995年
    • PHP :
    • Perl :
    • 「言語の世界じゃ10年くらいはまだまだはなたれ小僧」

新しい言語の動機

  • 作りたかったから
    • 30年前に雑誌とかみてて、プログラミング言語を作りたい、と思っている人が5人に1人とかいるだろうと思ってたら、実は全然いなかった
  • 新しいパラダイム
    • オブジェクト指向とか、関数型とか
    • ここ20年くらい新しいパラダイムは登場していないので、どちらかと言うとそれらの組み合わせ
      • 並列型と関数型の組み合わせ、とか
      • 組み合わせで難しいのはバランスよくする、使いやすくすること。組み合わせるだけなら簡単
  • 新しい環境
    • 新しいCPU、メモリが増える、
      • WEBとかMapReduceとかも「新しい環境」
      • PHPなんかはWEBで普及した言語
  • 新しい制約
    • データ量が爆発的に増える(ビッグデータ)、アクセス量

どこまでが言語か

  • 文法
  • ライブラリ
    • COBOLとか、言語そのものは古臭いかもしれないけど、業務システムのライブラリやそのデザインがCOBOLに最適化されていたりする
  • アーキテクチャ
    • ウェブそのものがアーキテクチャを支援しているような
  • デザインパターン
    • 本が出た時C++プログラマは喜んだが、Smalltalkでは当然のもの(言語に組み込まれている)だった
  • コミュニティ
    • ユーザーコミュニティ、開発者コミュニティ
    • 言語やライブラリよりも、コミュニティやエコシステムが重要。言語を選ぶときはそういう観点も大事にして欲しい
  • 思想・人格
    • 使っている人、作っている人の思想とか

温故知新 歴史の振り子

  • 集中 vs 分散
    • 昔はコンピュータが高かったので、コンピューターのところに行って、処理をお願いしていた
    • 中央のコンピューターに仕事を依頼する → 集中
    • コンピューターの性能が上がるよりも単価が下がる方が早かったので、処理を分散するように向かっていったらWEBが出てきた
    • ブラウザという形の汎用の端末を通して、データがサーバーに集まる → 集中へ
    • 今はみんな amazon に移行していってるが、amazonの中では分散されている(集中の中での分散)
  • 性能 vs 生産性
    • 1950年代には「世界中にコンピューターが5台あればいい」と言っていた人もいた
      • 人間はリソースがあればあるだけ使ってしまうという悪い癖がある
      • リソースは計算パワーにしても容量にしても、あればあるだけ使ってしまう
    • コンピューターの能力を若干無駄使いしても、その方が生産性が良かったり
  • 静的 vs 動的
    • 実行性能をとって柔軟にするか、その逆にするか
  • 正確さ vs 柔軟さ
    • 積極的により早く間違いを見つけようとするか、柔軟にしてTDDなどで間違いを見つけるアプローチか

未来にある言語はどういうものか

  • APL
    • 3年前のこのセッションで話しました
    • 記号を多用する配列言語。ライフ言語プログラムが1行で書ける
    • 昔は専用の端末を使わないと記号を打てなかったのが、今はユニコードなので全部入ってる
    • 予想通り、流行らなかった
  • Whitespace
    • スペースとタブで構成されているので、これを実行するとhello worldが実行される
    • ネタですけど
  • 「新しいぶどう酒は新しい革袋に」
    • これからの時代に即したプログラミング言語が必要
    • ビッグデータ、マルチコア、クラウド etc
    • Erlang / node.js / R / SQL の発展形

Erlang

  • 関数型 + 分散型
  • 信頼性の高い分散モデルを作れる
    • 大規模システムでCPUが増えたり、クラウドでシステムを構築するノードが増えた時、メッセージパッシングによる分散は価値を発揮できそう
    • Erlang がそのまま流行る、というよりも Erlang っぽい実装をされたり、 Erlang の後継が出たりとか

Node.js

  • サーバーサイドJSの典型
  • たくさんアクセスが来るからと言って実際のCPU数よりもスレッドを上げるとパフォーマンスが落ちる。それをカバーするために非同期IOによって多重化している
    • Node.js そのものが来るというよりも、既存の言語に大量アクセス対応をする機能がサポートするかもしれない

R

  • 統計、解析が非常に得意な言語
  • すたティスティクができるエンジニアの給料が上がっているので、統計ができる方はぜひ
    • Oracle が R-ODM という Oracle に対するアクセス機能がある R を作っている
    • ビッグデータと統計を組み合わせたものに未来があると思っている

sql

  • SQLそのもの、というよりも SQLの発展形
  • SQL の良いところは宣言的にデータを取得できる
    • 「こんなデータがほしい」といえば、裏で何やってるかわからないけどデータが出てくる。非常に抽象度が高い
    • こういう宣言度の高いものが来ると思っている
  • SQLそのもの、ではなく、宣言的に使えて結果が取得できるような何か

言語の楽しさ

  • プログラミングの楽しさ
    • 言語そのものが楽しい
    • なぜ言語が楽しいか、というと、やはり本質はプログラミングの楽しさ
  • 自分の思ったとおりにコンピュータが動くというのは楽しい
  • 中学の頃、ポケコンでBASICでプログラミングしてた
    • 400ステップとか
    • 命令した通りにコンピュータが動くのが可愛い。犬にお手ってやると手を出して可愛いのと同じだと思ってる
  • 言語 = プログラミング
    • 言語の楽しさはプログラミングの楽しさに密接な関連がある
  • 処理系を作るのがとても楽しい
    • コンパイラ → 構文解析
    • コンピュータサイエンスのあらゆる領域に、すこしずつ触ることができる
  • 言語設計
    • どんな言語を作るか
    • プログラミング言語によって発想の仕方が変わる。つまり、言語設計 = 発想をプログラミング
    • RUbyを使っているとRubyの発想にそまっていく
      • まつもとさんが決めた仕様なので、Rubyプログラマはまんまとまつもとさんにプログラミングされているw
Mac で Rails 3.2.1 を使おうとしたら、rails new するときにエラーになった。
% rails new myapp --skip-test-unit
      create
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app

...

      create  vendor/assets/javascripts/.gitkeep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.gitkeep
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
         run  bundle install
/Users/yz/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/net/http.rb:799: [BUG] Segmentation fault
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin10.8.0]

-- Control frame information -----------------------------------------------
c:0042 p:---- s:0226 b:0226 l:000225 d:000225 CFUNC  :connect
c:0041 p:0011 s:0223 b:0223 l:002620 d:000222 BLOCK  /Users/yz/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/net/http.rb:799
c:0040 p:0031 s:0221 b:0221 l:000220 d:000220 METHOD /Users/yz/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/timeout.rb:54
c:0039 p:0026 s:0209 b:0209 l:000208 d:000208 METHOD /Users/yz/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/timeout.rb:99
c:0038 p:0485 s:0203 b:0203 l:002620 d:002620 METHOD /Users/yz/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/net/http.rb:799

...

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

中略している部分も含めたすべてのエラーメッセージはココ
解決したので、以下対応履歴のメモ

環境は MacOS X 10.6.8 rvm 1.10.2 MacPorts 2.0.3

rvm のサイトにある通りにインストールスクリプトを叩いたらエラー。

 [ysato@localhost ~]$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)Downloading RVM from wayneeseguin branch stable

curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). The default
 bundle is named curl-ca-bundle.crt; you can specify an alternate file using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

Could not download 'https://github.com/wayneeseguin/rvm/tarball/stable'.
  Make sure your certificates are up to date as described above.
  To continue in insecure mode run 'echo insecure >> ~/.curlrc'.

エラーメッセージでぐぐると CentOS 5.5 に rvm で ruby をインストールする が見つかる。が、スクリプトを編集して証明書の警告を無視するオプションを追加、はあまりやりたくなかったので、別の方法を。

FacebookのAPIを使ってみようかと思って。
デベロッパーサイトでアプリを登録した。

アクセストークンはこんな感じで取れた。

HTTPs の接続の仕方がだいぶ怪しいので、後で直す。

【参考】 Facebookでテストユーザを作成する方法 - qui-no Labs

4/10の土曜日に、とべとべ自習室に行ってきました。会場は例によってオラクル青山センター。いつもいつもありがとうございます。 > @yokatsuki さん

特に何を作るか考えていなかったので、てきとーにTDDの勉強でもすっかなぁ、それか仕事でも使えそうな携帯用のプラグインでも書いてみるか、と思いながらTwitterで


http://twitter.com/yoozoosato/status/11921093691
と呟いたら、


http://twitter.com/ayumin/status/11921431143

という返信を@ayuminさんからもらったので、Rubyの勉強会(自習室)なのに、何故かずっとJavaを書くという不思議な会となりました。
# 多分Java書いてたのはウチらだけだったんじゃないかな? 久しぶりすぎて相当忘れてたけど。。。

手順メモ

(1) gem で RSpec, ZenTest, redgreen, autotest_screen をインストール。autotest_screenは、Version4.0未満のZenTestには同梱されていたみたいだけど、V4.0以降は別のgemをインストールする必要がある。

サイキョウライン » autotest_screenをリリースしました。

yoozoosato@localhost:~$ gem search rspec

*** LOCAL GEMS ***

rspec (1.2.9)
rspec-rails (1.2.9)
yoozoosato@localhost:~$ gem search autotest

*** LOCAL GEMS ***

autotest_screen (4.0.2)
yoozoosato@localhost:~$ gem search zentest

*** LOCAL GEMS ***

ZenTest (4.2.1)
yoozoosato@localhost:~$ gem search redgreen

*** LOCAL GEMS ***

redgreen (1.2.2)

(2) .autotest をホームディレクトリに作成。autotestでググると「サンプルをコピーすればいい」的な記述があったので、インストールしたgemの中に含まれているサンプルをホームディレクトリにコピーした。

cp /usr/lib/ruby/gems/1.8/gems/ZenTest-4.2.1/example_dot_autotest.rb ~/.autotest

(3) .autotestの中身を編集。require 'autotest/screen' を追記。ってか、元は全部コメントアウトされているから、コピーした意味ないじゃんね。。

# -*- ruby -*-

# require 'autotest/autoupdate'
# require 'autotest/once'
# require 'autotest/rcov'
# require 'autotest/restart'
# require 'autotest/timestamp'

# Autotest::AutoUpdate.sleep_time = o
# Autotest::AutoUpdate.update_cmd = o
# Autotest::RCov.command = o
# Autotest::RCov.pattern = o

require 'autotest/screen'

(4) 開発対象のディレクトリに「spec」と言う名前のディレクトリを作成し、その中に hoge_spec.rb みたいなテストを書く。
(5) 開発対象のディレクトリに移動して、 autospec コマンドを叩くと、specファイルが更新される都度テストが行われ、その結果がred/greenで表示される。
(6) こんな感じ。

・テスト失敗
20100105_1.png

・テスト成功
20100105_2.png

Mac + Growlの設定はぐぐれば沢山ヒットするけど、僕はgrowlが好きではないのでまだ試していない。導入してみてもいいような気もするけど。


Google App Engine でJRubyがかなり簡単に使える、ということで appengine-jruby を試してみた。

半年前に「準備だけした」アプリケーションがやっと稼働、っとw
http://yoozoosato.appspot.com/

Getting Startedのページに書いてあるものそのまんま大幅に端折って、1個のGETリクエストだけを処理する極めてプレーンなSinatraアプリ。
一応、HTML5完全準拠です。

ソースは以下。
勉強会の会場情報からMapsにドンピシャでピンを立てられるかの続き。 IT勉強会カレンダーが持っている「場所」の情報をGoogle Mapsのgeocoding apiで緯度経度の情報に変換したい。ということで該当部分のrubyソースコードはこんな感じ。

 
      result =
        Net::HTTP.Proxy(HTTP_PROXY_HOST, HTTP_PROXY_PORT).get('www.google.com',
                                                              '/calendar/feeds/' +
                                                              calendar_id +
                                                              '/public/full/?' +
                                                              query_parameter)
      doc = REXML::Document.new(result)
      doc.elements.each('feed/entry') do |node|
        titleTag = node.elements['title'].text.scan(/^\[.+\]/)[0]
        latLngResult =
          Net::HTTP.Proxy(HTTP_PROXY_HOST, HTTP_PROXY_PORT).get('maps.google.com',
                                                                '/maps/geo?key=ABQIAAAAoNeNuyCEgoxGqOs0M2LDVRSEjokCM-_tycVHGOP0c6-HsV-cXxSOYcZzGZclhsHo1FzsTnLFVQuCOg&sensor=false&output=csv&q=' +
                                                                node.elements['gd:where'].attributes['valueString'])
        logger.debug(node.elements['gd:where'].attributes['valueString'] + "\t" + latLngResult)
        ....
      end

結論から言うとgeocoding-apiじゃ無理w
身も蓋もないけど、無理

irb便利だ〜
irb(main):013:0> result = Net::HTTP.Proxy('proxy.mycompany.co.jp', '8080').get('maps.google.com', '/maps/geo?key=YOUR_API_KEY&q=東京タワー&sensor=false&output=xml')
irb(main):014:0> puts result

すると、resultにどんなxmlが入っているかすぐ分かる。

このアーカイブについて

このページには、過去に書かれた記事のうちRubyカテゴリに属しているものが含まれています。

前のカテゴリはrecipeです。

次のカテゴリはServicesです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

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