6月 09

オブジェクト指向を理解してない私がプロトタイプベースのオブジェクト指向言語のIOを触ってみました(『7つの言語 7つの世界』第3章)

7つの言語 7つの世界』(オーム社)を読みながら、IOという言語で少し遊んでいます。プロトタイプベースの言語なので、オブジェクトがクラスの代わりになるんだそうで、オブジェクトを複製してさらに別のオブジェクトを作成したり、インスタンスを生成したりします。
 
 IO言語については以下の解説をご覧ください(私には解説はムリぽ)。
io(公式サイト。ダウンロードもこちら)
Io (プログラミング言語) – Wikipedia
Rubyist Magazine – Rubyist のための他言語探訪 【第 3 回】 Io

 といいつつも、メモ程度には書いてみたいと思います(そのほうが書いた方が理解しやすいので)。

1.最初の儀式

 まずはということで、”Hello,World!”。

Io> "Hello, world!" println
Hello, world!

 

2.プロトタイプチェーン

 ルートレベルのオブジェクトはObjectオブジェクトです。このObjectオブジェクトからこんな感じでオブジェクトを複製します。

Io> Thing := Object clone
==>  Thing_0x46ff60:
  type             = "Thing"

 これはOjectオブジェクトを複製して、Thingという変数に代入することで、Objectオブジェクトを複製したThingオブジェクトを作成している、という理解でよいのですかね。同じようにThingオブジェクトを複製して他のオブジェクトをつくることができます。

Io> CreativeWork := Thing clone
==>  CreativeWork_0x475980:
  type             = "CreativeWork"

Io> Blog := CreativeWork clone
==>  Blog_0x47b3d0:
  type             = "Blog"

 ここまでで、プロトタイプチェーンは以下のような感じになります。
Object > Thing > Creativework > Blog

 たとえば、Thingオブジェクト内に “description”というキーを持つプロパティを定義してみます(「スロット」というらしいです)。

Io> Thing description := "The most generic type of item. "
==> The most generic type of item.

 当然ですが、BlogオブジェクトはThingオブジェクトを継承したCreativeWorksオブジェクトを継承しているので、Blogオブジェクトで”description”をキーに持つスロットを定義していなければ、以下のようにThingオブジェクトで定義したスロットが引き継がれます。

Io> Blog description
==> The most generic type of item.

 
 当然、Blogオブジェクトでdescription”をキーに持つスロットを定義してやればそちらが優先されます。

Io> Blog description := "A blog"
==> A blog
Io> Blog description
==> A blog

3.インスタンス?

 これまで、Thing、CreativeWork、Blogという頭文字が大文字のオブジェクトばかり生成してきました。小文字にすると、インスタンスっぽいものを生成することができるようです(多分、インスタンスですよね・・)。といってもインスタンスもオブジェクトなので、大文字と小文字の違いは独自のtypeをもつか、もたないかぐらいの違いしかないようです。

Io> myBlog := Blog clone
==>  Blog_0x2b4290:
Io> myBlog type
==> Blog

 はぁ〜と思ったのが、頭小文字(インスタンス?)を複製して頭大文字のオブジェクトを生成することができるようで、「他の言語(Rubyぐらいしか知りませんが)だとどうだったか・・・・」とかいろいろと。

Io> MarchEntry := myBlog clone
==>  MarchEntry_0x4567e0:
  type             = "MarchEntry"
Io> MarchEntry type
==> MarchEntry
Io> MarchEntry description
==> A blog
Io> myBlog description := "更新頻度低め"
==> 更新頻度低め
Io> MarchEntry description
==> 更新頻度低め

 この場合、継承関係はこうなるのでしょうか。
Object > Thing > Creativework > Blog >myBlog > MarchEntry

4.シングルトン

 上で以下のようにBlogオブジェクトを生成しました。

Io> Blog := CreativeWork clone
==>  Blog_0x47b3d0:
  type             = "Blog"

 
 もう一度BlogオブジェクトをCreativeWorkオブジェクトから複製して生成すると同じオブジェクト名であっても、異なるオブジェクトが生成されます。

Io> Blog := CreativeWork clone
==>  Blog_0x48d3f0:
  type             = "Blog"

 

 しかし、以下のように一度生成したBlogオブジェクトをBlogオブジェクトを複製するときに代入すると、”Blog_0x48d3f0″という全く同じオブジェクトが生成されます(「シングルトンオブジェクト」というかしら?)。

Io> Blog clone := Blog
==>  Blog_0x48d3f0:
  clone            = Blog_0x48d3f0
  type             = "Blog"

 
 このシングルトンオブジェクトから生成したインスタンスは異なる名前を当てても同じオブジェクトになるようです。

Io> hisBlog := Blog clone
==>  Blog_0x48d3f0:
  clone            = Blog_0x48d3f0
  type             = "Blog"

Io> herBlog := Blog clone
==>  Blog_0x48d3f0:
  clone            = Blog_0x48d3f0
  type             = "Blog"
Io> hisBlog == herBlog
==> true

 

 プロトタイプベースのオブジェクト指向言語では、オブジェクトがクラスの役割を果たすというのはわかってきたような気もしないでもないですが、正直まだよく分からない部分が多いですね。少なくともクラスベースのRubyではどうだったかなという疑問はすぐに確認しておいたほうがよさそう。

 『7つの言語 7つの世界』でIOを取り上げた章の2/3を読んだところです。あと1/3がんばります。

10月 26

JavaScirptをブラウザ上で組んでそのまま気軽に実行できるWebサービス

 見つけては時間が経つと忘れ、また再発見してはまた時間が経つと忘れ・・・を繰り返しているのでまとめみました。書いたらさすがに忘れまい。ブラウザ上でJavaSript実行できて当たり前じゃんというツッコミが来そうですが、いちいちテキストエディタ立ち上げてコード組んでとかじゃなく、フォームに書いてホイとすぐに試せるサービスをここでは指してます。マニュアルを読みながらサンプルコード実行してみたいだけなのに、jQueryなどのライブラリをダウンロードして・・とか環境整えるだけでも結構面倒でしょ。
 

jsdo.it

 Web上で書いてWeb上で実行できるオンラインエディター、そして、それを他の人とシェアするサイト。HTML5関連のAPIを試している人が沢山いるので探すといろいろとでてくる。jQueryな人も沢山おるようです。

jsdo.it – Share JavaScript, HTML5 and CSS
http://jsdo.it/

 

jsfiddle

 上のjsdo.itはどちらかというと気軽に試すという感じですが、こちらは本格的にオンラインエディターという感じのWebサービスです(試していないのであくまでイメージ)。jQueryやprototypeなどのライブラリのいろいろなバージョンを試せるというのも便利そう。

jsfiddle
http://jsfiddle.net/

ブラウザ上でHTML / CSS / Javascriptを書いてその場で実行、ブログ等にも貼付できるjsfiddleの基本的な使い方をざっくりと – かちびと. net

 

jsPerf

 jsPerfはこのエントリの趣旨から少し離れてしまいますが、便利そうなのでいっしょに掲載しておきます。JavaScritの実行速度の比較ができるサービスのようです。

jsPerf: JavaScript performance playground
http://jsperf.com/
 
 詳細は以下をご覧ください。

JavaScriptコードのパフォーマンス比較ができるWebサービス「jsPerf」の使い方 | Web scratch

10月 19

W3Cで策定中のモバイル向けWebアプリを進化させるHTML5関連のデバイスAPI

 今、JavaScript関係の本を読みつつ、HTML5関係の本もぱらぱらと並行して読んでます。JavaScriptに対する理解がまだまだ全然なので、「サンプルコードとか、もう読むのが辛い・・」、「いや、もう、どんなこと書いてあるかその概要がざっと読めればいいや」、「いや、コードの気の流れが理解できればいいや」・・とハードルを下げ続けて現在に至ります。 といいつつも、HTML5面白いなあとほんわか感じています。
 
 Webアプリがネィティブアプリに機能的に近くなるのは、HTML+CSS+JavaScrptでできることが格段に増えるということで、Rubyを少しかじった程度のなんちゃってコーダー(笑)としては、「CやJavaを覚えずとも、JavaScriptでいけるんか!」とヘタレな感じですが、嬉しい限りです。とはいえ、現状ではWebアプリとネィティブアプリでは、以下のブログで紹介されているようにそれぞれ一長一短があるようです。

ネイティブアプリとウェブアプリ(Webアプリ)のメリット・デメリットまとめ – hachimitu blog

 しかし、上で言及されているようなカメラやセンサーなどのハードウェア固有の機能を操作できないというWebアプリの欠点は将来的に解消されていくのかもと思わせる仕様の検討がW3Cでされているようです。W3Cで検討されている仕様は膨大にあって、私はTwitterで流れてくる情報を追うのが精一杯ですが、その中で拾えた仕様のいくつかをまとめてみました。ちなみにここではいくつもものW3Cの仕様を紹介していますが、私はまだ読んでません(汗)。これからこういうのを読みたいという思いでまとめたという意味もありますのでご容赦ください。ここで書かれている事に対する間違い等のご指摘は大歓迎です。

■DeviceOrientation Event Specification

 デバイスの向きや動きに関する情報のDOMを定義している仕様です。つまり、デバイスの向きや動きを探知するセンサーをつかっていろいろとできる仕様のようです。とまあ、ちょっと知ったかぶってみましたが、後述の羽田野太巳(@futomi)さんのツィートでその存在を初めて知りました。

DeviceOrientation Event Specification
http://dev.w3.org/geo/api/spec-source-orientation.html 

 この仕様はまだEditor’s Draftの段階でまだまだ確定にほど遠いはずなんですが、HTML5.JPの羽田野太巳(@futomi)さんによる10月15日付けの以下のツィートによるとiOSデバイスではすでに実装されているようです。時期的にiOS5アップデート後のSafariについて言及されているのだろうと思いますが、すごいですね。

 この仕様については日本の情報も比較的多い。 

ヅラッシュ! – Android 3.0 端末の傾きを JavaScript Device Orientation で取得するサンプル
DeviceOrientation Eventでシェイク!iPhoneウェブアプリで使ってみる | 岡山のウェブサイト制作プロダクション “ニイハチヨンサン” のブログ
Chromeでも加速度センサー(DeviceOrientation Event)が使える様になってたみたい – 強火で進め
 
 

■WebRTC 1.0: Real-time Communication Between Browsers

 
音声や動画のリアルタイム通信機能を行うための仕様が以下のWebRTCという仕様で、Skypeのようなチャットなどに使われることを想定しているようです。カメラ、ビデオカメラ、マイクロフォンなどデバイスのインターフェイスから得た情報をHTML5に対応したブラウザで扱うことができるAPIらしい。まだEditor’s Draftの段階で、実装しているブラウザは後述の秋葉秀樹(@Hidetaro7)さんが紹介するAndroid用の開発版Opera Mobileぐらいなのでしょうか?

WebRTC 1.0: Real-time Communication Between Browsers
http://dev.w3.org/2011/webrtc/editor/webrtc.html

Chromeブラウザ初の「WebRTC」実装発表 – JavaScript/HTML5でIMを簡単開発 | エンタープライズ | マイコミジャーナル
MozillaがWebRTCグループ参加を正式表明~Firefoxへの統合も視野に -INTERNET Watch
HTML5ブラウザで音声や動画のリアルタイム通信機能「WebRTC」 :: dotHTML5
 
 この仕様は秋葉秀樹(@Hidetaro7)さんの以下のブログのエントリでその存在を初めて知りましたが、そのエントリで紹介されているようにカメラアプリなどの開発に活用することもできるようです。個人的にはチャットよりもこちらのほうが興味深いので、このエントリでも紹介させていただきました。 

HTML5でつくるカメラ&落書きアプリ(中国GTUGハッカソンで発表) | 秋葉秀樹個人ブログ 
HTML5-WEST.jp 勉強会「HTMLでつくるカメラ&落書きアプリ」フォローアップ | 秋葉秀樹個人ブログ
 

■Device APIs Working Groupが策定を進めている仕様群

 W3CのDevice APIs Working Groupが策定を進めているAPIの仕様群です。面倒ですが、”Priority APIs”と”Other”に挙げられているAPIで仕様がドラフトでも公開されているものを自分の勉強がてら以下にリスト化してみます。以下で全部ではもちろんありません。詳しくはDevice APIs Working Groupのサイトをご覧ください。デバイス関係だけでいろいろなAPIがありますねぇ・・・・。

Priority APIs
Battery Status Events(2011/10/18時点でPublic Working draft)
Contacts API(reading from addressbook)(2011/10/18時点でLast Call)
HTML Media Capture(2011/10/18時点でPublic Working draft)
The Messaging API(SMS, MMS, emails)(2011/10/18時点でPublic Working draft)
The Network Information API(2011/10/18時点でPublic Working draft) 

Other
Calendar API(2011/10/18時点でPublic Working draft)
Feature Permissions(2011/10/18時点でEditor’s Draft)
The Media Capture API (programmatic access to camera/microphone)(2011/10/18時点でPublic Working draft)
Sensor API Specification(2011/10/18時点でEditor’s Draft)
Permissions for Device API Access(2011/10/18時点でPublic Working draft)
  
 仕様を読んでいないのでよくわかりませんが、ここで検討されているHTML Media CaptureThe Media Capture APIを使ってでも将来的にカメラアプリやビデオカメラアプリなどのWebアプリが作れたりするのでしょうか。その辺、もう少し勉強してみたいところです。

 ”Other”にあるSensor API Specificationはデバイスが持つ様々なセンサーが提供する情報にアクセスするためのAPIを定めた全般的な仕様のようです。最初に紹介した”DeviceOrientation Event Specification“やGeolocation APIなどの上位にくる仕様ということでしょうか?デバイスがもついろいろなセンサーを活用することができるAPIの仕様のようです。センサーやカメラなどハードウェアが持つ機能をHTML5対応のブラウザからアクセスしたり、操作したりできるようになるといよいよ面白くなりそうですね。 

 

■さらにスコープを拡げて>Ubiquitous Web Applications Activity

 これまで紹介した仕様はUbiquitous Web Applications Activity下のWorking Group(分科会)で検討されている仕様です。他にもいろいろとありそう。じっくり調べてみたいところです。

Ubiquitous Web Applications Activity
http://www.w3.org/2007/uwa/Activity.html 

 

10月 04

RubyConf 2011の発表資料

9/29から10/1に米国で行われたRubyConfの発表資料がいくつかslideshareで公開されているようです。今なら「Rubyconf」で検索してさらに結果を「this month」で期間を絞れば結構出てきます。どこかでまとめられているともっとよいのですが、今のところないみたいです。

RubyConf 2011
http://rubyconf.org/

 会議の様子はRubyコミッタのauthorNariさん(Nariさん?)がブログで紹介してくださったりしています。

Rubyconf参戦記 -0日目- – I am Cruby!
Rubyconf参戦記 -1日目- – I am Cruby!
Rubyconf参戦記 -2日目- – I am Cruby!
Rubyconf参戦記 -3日目- – I am Cruby!
Rubyconf参戦記 -4日目- – I am Cruby! 
Rubyconf参戦記 -最終日- – I am Cruby! 

 以下に上げている発表資料は会議で発表されているもののほんの一部です。

 

 
 

10月 03

JavaScriptはじまりました(私の中で)

 飽きっぽさを見事に発揮してRubyもまだまともに使いこなせない私がJavaScriptにも手を出し始めました。


 
 といっても、今は『JavaScript本格入門 ~モダンスタイルによる基礎からAjax・jQueryまで』を読んでいるだけです。JavaSriptを真正面から体系的に紹介する本はオライリーの本を除けば、あまり多くはないようで、しかも、この本のように初級者向けに丁寧に書かれた本となると非常に希有のようです。お勧めです。

 始めた動機はRubyの特徴を理解するには他の言語のことも理解しなくてはということと、HTML5関係でいろいろとあそぼうと思ったらJavaSriptは必須ということでわりと真面目にやっています。Rubyを頑張って勉強してきたおかけで、プログラム言語を初めて学ぶような障害は余り感じることがなく、ふむふむと読んで分かった気になっております。

とはいえ・・・

プロトタイプ型のオブジェクト指向・・・よくわからんぞ・・・

 

クラスの役割をオブジェクトを代替させている?

でも、Rubyのクラスだってオブジェクトじゃん??

細かな挙動の違いは方言の違いというレベルでは???

いやいや、待て待て。 

プロトタイプ型とクラス型の違いはそんなちっちゃな違いじゃないはず!
  

 そもそも上のような疑問自体、根本的になにか間違っているのではないのか?そもそも日本語として正確なのか??
 

(っ`Д´)っ・:∴ゴルァ!!!!!!
 

と悶々としております。

 それにしてもJavaScriptは中括弧({})の使用が多いような・・。

 分かった気になっている部分も実際に書いてみないと分かりませんしね。

 最近、HTML5関連の動向を取り入れたJavaSript本が沢山出ていますね。以下のタイトルは結構気になります。 
 

パーフェクトJavaScript (PERFECT SERIES 4)
パーフェクトJavaScript (PERFECT SERIES 4)
クチコミを見る
 
改訂第5版 JavaScript ポケットリファレンス
改訂第5版 JavaScript ポケットリファレンス
クチコミを見る
 
JavaScriptクックブック
JavaScriptクックブック
クチコミを見る

 

9月 29

Rubyのinstance_evalメソッドについて分かってきたような気もするが疑問も増えた

 Rubyのinstance_evalがブロック内のテキストを評価してレシーバーであるインスタンスの元で実行するメソッドであるということは、irbを叩いてなんとく理解できつつあるような気がします。しかし、逆に「何故そうなるのか?Why?」という疑問も増えてきました。

 

メソッド

 以下のように定義したメソッド”aaa”はStringクラスのインスタンス”str”の特異メソッドになるようです。

str = "hoge"

str.instance_eval{def aaa; puts "a";end}
str.aaa
⇒"a"

 しかし、このインスタンスメソッド”aaa”で返された”a”は文字列であるはずなので、Stringクラスかと思いきや、NilClassらしくて、この理由がよくわからないんですよね。 

str.class
⇒String

str.aaa.class
⇒NilClass</del>

 
  ちなみにFixnumクラスを返すはずのインスタンスメソッド”bbb”でも同じ結果です。 

str.instance_eval{def bbb;puts 1;end}
str.bbb
⇒1

str.bbb.class
⇒NilClass</del>

追記
「putsの戻り値がnilだからでは」というコメントをいただきました。試してみると確かにその通りでした。失礼しました。

str = "hoge"

str.instance_eval{def aaa;"a";end}
str.instance_eval{def bbb;1;end}
str.aaa.class
⇒String
str.bbb.class
⇒Fixnum

 

定数

  インスタンスの中で定数を定義してみます。正直、インスタンスの中で定数を定義することの意味がまだよくわかりませんが、一応可能なようです。これは特異定数というか、インスタンス定数という感じになるのでしょうか・・・?
 

str.instance_eval{AAA = "ccc"}

 

この定数”AAA”はどこで定義されてだろうか?
どうやって参照するのだろうか?
 疑問が次から次へと出てきて止まりません。 

クラス – class_evalとの違い –

 さらにこのインスタンス”str”の中でクラスを作ってみたいと思います。
 

str.instance_eval{class BBB;end}

BBBクラスのインスタンスはつくることができます。

b = BBB.new
b.class
⇒BBB

Objectクラスのすぐ下にクラスが作られるんですね。Stringクラスのインスタンス”str”の中で作られるので、Stringクラスのサブクラスとして生成されるかと思っていました。

BBB.ancestors
⇒[BBB,Object,Kernel]

 

 もう少し深く考えるとこの辺の挙動が理解できそうなのですが、今のところ???状態です。

 ちなみにクラスはClassクラスのインスタンスでもあるので、instance_evalを用いるとこんな感じになります。

CCC = Class.new
#これでCCCクラスの生成。
CCC.class ⇒Class
#CCCはClassクラスのインスタンス

 Classクラスのインスタンス、”CCC”にメソッドと定数を定義しています。

CCC.instance_eval{def ccc;puts "123456";end}
CCC.ccc
⇒"123456"

CCC.instance_eval{EEE = "789101112"}
CCC::EEE
⇒"789101112"

 

 それぞれクラスメソッドとクラス定数として定義されているようです。クラスメソッドに定義されるのはClassクラスのインスタンス”CCC”の特異メソッド(=クラスCCCのクラスメソッド)として定義されているからです。Classクラスのインスタンスをレシーバーにする限り、instance_evalとclass_evalと違いは無いような気がする。どうなのだろう?  
 
 

9月 25

Rubyがインストールされていない環境下でRubyのirbをなんとか使う方法

 Rubyのマニュアルを読んでいると、サンプルとして掲載されているプログラムを実行して挙動を確認したいということがままあり、そういう時にirbは非常に重宝しています。しかし、移動している時などいつも手元にRubyがインストールされている環境があるわけではありません。そんなときでもirbを使う方法をまとめてみました。
 

Web

 Webベースのirbです。ネットに接続された環境下ならブラウザ上でirbを使用することができます。

try ruby! (in your browser)
http://tryruby.org/

 

For iOS

 私はiPhoneユーザーですので、一番よく利用しているのが以下のアプリです。移動中にRubyのマニュアルを読みながらメソッドの挙動などを確かめるのに非常に重宝しています。これもネット経由でリモートにirbを利用するサービスです。

irb for iPhone
http://itunes.apple.com/jp/app/irb/id409540962?mt=8
irb for iPhone
 

 Googleで「irb for iPhone」で検索するとiOSでirbを使えるようにしようという試みはいくつもされているみたいです。ここういうのがどんどん生まれてくるといいですね。できれば、ローカルで実行できるものが欲しい。 

 

For Android

 これはもしかするとAndroidにJRubyをインストールするものなのでしょうか。ならば正確には「Rubyがインストールされていない環境下」とはいえませんが、趣旨としては同じなので紹介してみます。とはいえ、私はAndroidユーザーではないので使用したことがありませんが、対話的に実行するirbが使えるだけではなく、Editorも用意されているようですので、コピペなどを駆使すればローカルで書いたスクリプトを実行もできるんではないでしょうか。正直、これは非常にうらやましい。

Ruboto IRB : 過去最大の衝撃。これは凄い!!AndroidでRubyが動く!!Androidアプリ427

Ruboto (JRuby on Android)
http://ruboto.org/

 

9月 25

Ruby(1.8.7〜1.9.0)の配列の末尾には見えない要素があるらしい。

 少し細かい話を・・・・。

 『プログラミング言語Ruby』の「9.5.2.3 配列要素の書き換え」(p353)にsliceメソッドの解説に以下のようなサンプルコードが掲載されています。

# slice!で要素、部分配列を削除
a = [1,2,3,4,5,6,7,8]
a.slice!(0)
# => 1: 添字 0 の要素を削除: a は[2,3,4,5,6,7,8]
a.slice!(-1,1)
# => [8]: 末尾の部分配列を削除: aは[2,3,4,5,6,7]
a.slice!(2..3)
# => [4,5]: 範囲を受け付ける: aは[2,3,6,7]
a.slice!(4,2)
# => []: 末尾の位置にある空配列: a は変更されず
a.slice!(5,2)
# => nil: a は [2,3,6,7,nil]に

1行目から8行目まではよくわかるのですが、9行目と11行目がよく理解できませんでした。同じ配列の範囲外を指定しているのに、なぜ9行目が空の配列を返し、11行目がnilを返してくるのかと。

 当然ですが、クラスも異なります。

a.slice!(4,2).class
#⇒ Array
a.slice!(5,2).class
#⇒ Nilclass

 

 う~ん、よくわからん。配列の末尾には

[2,3,5,6,(nil)]

 

という感じで見えないnilの値でも入っているのだろうかと、眠れない夜が続いていた(嘘)のですが、Rubyに詳しい方にこの件についてお尋ねする機会があったので伺ってみると、配列には見えない形で末尾に配列の末端であることを示すデータが入っているらしいのだそうです。C言語で書かれているのでその実装上の問題とか・・。C言語はよくわかりませんが、そうなんですか・・・。

つまり、

a ⇒[2,3,5,6,(配列の末尾であることを示す見えない要素)]

であるので、

a.slice!(4,2)
# => []

 

 と、空の配列を返すのだそうです。なるほど!そして、以下の場合

slice!(5,2)

 

 以下の■の部分のような配列の外を第一引数が指してしまうので、nilが返ってくるということになるらしい。なるほどぉぉお。

a ⇒[2,3,5,6,(配列の末尾であることを示す見えないデータ)] ■←ココ!

 

ちなみに

 『プログラミング言語Ruby』では以下のようにa配列の5番目の要素に”nil”が追加されますが、

a.slice!(5,2)
# => nil: a は [2,3,6,7,nil]に

 

 私のMacでは以下のようになります。a配列に5番目の要素に”nil”が追加されたりはしません。ちなみに私はRuby 1.8.7を使用しています。『プログラミング言語Ruby』は1.9.0までフォローしています。

a.slice!(5,2)
# => nil: a は [2,3,6,7]に

 

 この辺はRubyの実装環境の違いなんでしょうか・・・。

 ちなみにWebベースのirbであるtry ruby!で試したRuby 1.9.2だとArgumentErrorを返すようです。バグとして修正されたのでしょうか。

a = [2,3,6,7]
=> [2,3,6,7]
>> a.slice[4,2]
ArgumentError: wrong number of arguments (0 for 1..2)
>> a.slice[5,2]
ArgumentError: wrong number of arguments (0 for 1..2)

 

9月 24

RubyのClassクラスのインスタンスの定数はどこで定義されているのか

  RubyのクラスはClassクラスのインスタンスらしい。なるほど。

つまり、以下のようにABCクラスを作るとClassクラスのインスタンスが生成されるらしい。

Class ABC

end

ABC.class
=> Class

 そして、クラス名は定数なのだそうだ。上の場合だと”ABC”は定数でもあるらしい(だから、クラス名の最初は大文字)。Classクラスのインスタンスを定数ABCに代入しているということらしい。

上でクラスの作成は以下のように書くこともできる。

ABC = Class.new{ }

 より定数に代入しているっぽいですね。

 ならば、このクラス名の定数”ABC”はどこのクラスで定義されているのだろうかと。

 ちょっと調べたら簡単にわかりました。以下のようにObjectクラスの定数としてクラス名は定義されているようです。

p Object.constants.grep /ABC/
⇒ ["ABC"]

Rubyのその他の組み込みクラスのクラス名もObjectクラスに定数として定義されています。さきほど私が定義したクラス名ABCも含めて。

p Object.constants
=> ["ThreadError", "RUBY_PLATFORM", "Regexp", "Deprecate", "Numeric", "String",
"SLex", "Bignum", "IndexError", "SecurityError", "UnboundMethod", "Exception",
"Readline", "RubyLex", "NoMethodError", "FALSE", "Object", "RELEASE_DATE", "IRB",
"Range", "IO", "Integer", "Config", "TypeError", "RubyToken", "Dir", "RUBY_VERSION",
 "ZeroDivisionError", "Gem", "SystemExit", "NotImplementedError", "Hash", "RegexpError",
"Kernel", "TOPLEVEL_BINDING", "RUBY_COPYRIGHT", "GC", "TRUE", "STDOUT", "LocalJumpError",
"Binding", "Interrupt", "RUBY_FRAMEWORK", "ObjectSpace", "SyntaxError", "Marshal",
"Enumerable", "Struct", "Class", "Continuation", "IOError", "MAXHISTSIZE", "RangeError",
"Kconv", "Data", "Thread", "RUBY_PATCHLEVEL", "SystemStackError", "Array", "NoMemoryError",
 "FileTest", "MatchData", "ARGF", "ETC_IRBRC_LOADED", "NIL", "Comparable", "PLATFORM",
 "ArgumentError", "Float", "FloatDomainError", "RUBY_RELEASE_DATE", "RuntimeError",
"Precision", "ThreadGroup", "Signal", "Fixnum", "STDERR", "FalseClass", "VERSION",
 "Exception2MessageMapper", "RbConfig", "Errno", "StandardError", "Math", "EOFError",
 "LoadError", "NKF", "RUBY_FRAMEWORK_VERSION", "APPLE_GEM_HOME", "STDIN", "TrueClass",
 "NameError", "NilClass", "Process", "Proc", "RUBY_DESCRIPTION", "ARGV", "ABC",
"SystemCallError", "SignalException", "MatchingData", "File", "Time", "ENV",
 "ScriptError", "Symbol", "Module", "Method", "StopIteration",
"DTracer", "CROSS_COMPILING", "HISTFILE"]

 なるほど。なるほど。なるほど。