新潟の Rubyist で集まりましょう! Ruby に興味があるという方もご参加ください!
新潟の Rubyist が集まるイベント : ATND
これね。
「とりあえず新潟って最近Rubyな人の集まりが全然ないよね。どんな人がいるのか知りたいね」ということで id:jewel12 先生が企画してくれました。
普段から「勉強会の本番は懇親会」論を唱える側の僕ですが、今回は本当に飲み会のほうが本番です。
ただ、初心者が多いということで、昼間にギークハウス新潟で初心者向けの「かんたん♪Ruby講習会」が行われました。
各種資料
環境
OS | 自由 |
---|---|
Rubyバージョン | 1.9系推奨 |
OSはWindowsやLinuxが多数派で、珍しいことにMac持ってきてるのが僕だけでした。
Linux使ってた id:saisa6153 先生が「MBPにコーヒーこぼして壊したから今Retina MBP待ちなんですよ!!」とか主張しててマジウケた(外道)
内容
始まる前までの僕が持っていたRubyに関する知識
- Matzさんが作った
- 島根がゴリ押ししてる
- Ruby合宿とか講師陣がガチすぎてやばい
- RubyVM上で動作する言語
- 全ての値はオブジェクトである
- Javaのboolean, char, byte, short, int, long, float, doubleのようなプリミティブ型は存在しない
- なので「1」のような数値は「数値(1ならInteger)クラスのオブジェクト」であり、「1.to_s」のようなメソッドを持つ
- 実は新潟で一度盛り上がりそうになったけど立ち消えた歴史がある(後述)
- 僕が書いたCorona本*1でお世話になっている達人出版会の高橋さんが会長をやっている日本Rubyの会というのがある。
- RubyKaigi 2011の会期とCorona本の発売日をぶつけちゃって高橋さんには正直スマンカッタと思っている
- 2011年にITコミュニティではなく一般社団法人として再スタートを切ったらしい
勉強会パートでは1つもこの辺の話が出てこなかったので、僕が知っていたRubyの知識は本当にRubyに関するものだったのか不安になりながら過ごしていました。
新潟とRuby
今、僕がいる会社は新潟産業創造機構(NICO)のお世話になっているわけなんですが、NICOの人から「何年か前に新潟でもRubyの勉強会がちょこちょことあったんだけどね」みたいな話を聞いたことがあって、当時の参加者達はコミュニティ活動もせずにどこへ消えてしまったんだろうという疑問がありました。
ということで、新潟とRubyのキーワードで引っかかる、過去のイベントをピックアップ。
2007/12/01 | Ruby勉強会@新潟 第1回のお知らせ *2 |
---|---|
2007/12/05 | Rubyビジネスセミナー@新潟(Matzさん来てた) |
2008/03/15 | Ruby勉強会@新潟 第2回のお知らせ |
2008/04/19 | イケテルrails勉強会@新潟第1回について |
2009/01/10 | 第2回NDS(第1回イケテルRails勉強会@長岡)参加したよ |
2009/03/07 | 朱鷺メッセで「Ruby勉強会@新潟」が開催 |
簡単に探してみて出てきたのはこれだけ。多いかどうかはわからないけど、けっして少なくはないと思う。2007年末から2009年初めにかけて、新潟ではRubyのセミナーがそれなりに流行っていた、とは言えそう。
そして調べてみると飲み会にいた「いたさん」が当時のRuby振興にかなり貢献していたのがじわじわ見えてくる。あの人只者じゃないと思ってたけど本当に只者じゃなかった・・・!
いたさんみたいな方がいても続かなかったあたり、やっぱり技術者コミュニティを続けていくのって大変なんだなあ、とも思ったりした。
ということで、漏れがあるかも知れませんが今回のが概ね3年ぶりくらいのパブリックなRubyの勉強会になったようです。
今回の勉強会で分かったこと
勉強会中の疑問点1
「+記号で文字列結合するって話だけど、数値同士を文字列結合したい場合ってどうすんの?」
PerlやPHPやLuaなどの場合は、加算と文字列結合の演算子を別に用意しているので、この疑問は出てこないんですよね。
# Perlの場合 my $a = 1; my $b = 2; print($a.$b); # 12 print($a+$b); # 3
-- Luaの場合 local a = 1 local b = 2 print(a..b) -- 12 print(a+b) -- 3
Rubyの場合は、+演算子が文字列同士なら結合、数値同士なら加算と、ハッキリと役割が分けられています。
(今考えるとRubyの場合は普通の「演算子」だと思っていたこと自体が間違っていた*3のですが・・・)
それまで習っていた内容から僕が出した答えはこれ。
a = 1 b = 2 puts "#{a}#{b}" #=> 12 puts a+b #=> 3
ダサすぎて死にたくなりました。
まさか天下のRuby様が数値の文字列結合ごときにこんなダッサいソリューションしか用意してないわけないので、 id:jewel12 先生に質問してみました。答えはこれ。
a = 1 b = 2 puts a.to_s + b.to_s #=> 12 puts a+b #=> 3
「ダサい版より文字数増えてんじゃん・・・駄目じゃね・・・?」と最初は思ったものでしたが、『数値型もオブジェクト』という文化をまだちゃんと理解しきれていなかった自分を再確認できました。
ちなみにこのあと、飲み会でこの話題になったときに色々と意見を聞いて、ああ、これはこれで正しいんだ、と頷くことになりました。
わかったこと
Rubyは「何」と「何」を+で繋ごうとしているのかを考えることを僕らに強要してくれているのです。
変数に型を指定しない以上、その変数の中身が数値なのか文字列なのか他の何かなのか、実行するまで僕らには分かりません。
例えば、Luaには暗黙の型変換がないので、以下の様なことが起こりえます。(かなりアホな例ですが)
local number1 = 1 local number2 = "two" -- +してはいけないのに変数名が紛らわしいので間違えて+しちゃう print(number1 + number2) -- エラー:attempt to perform arithmetic on local 'number2' (a string value)
Rubyでも暗黙の型変換は原則行われないらしいので似たようなことは起こりうるのですが、文字列結合専用の演算子を用意しないことで「2つのオペランドが数値同士か文字列同士だと確実にわかっているとき以外の文字列結合では、to_sメソッドで両方のオペランドを文字列にしてから+しろよ」という文化を生み出しているようです。
Rubyよくできてんな。
勉強会中の疑問点2
よく出てくる|hoge|ってなんぞ
こういうコードですね。
5.times do |i| puts i end
id:jewel12 先生に「この縦棒で囲まれてる変数って何なん?」と質問したら、なんだか実例を色々と見せていただけましたが、途中でlambdaとか使った実例も出てきて、まあみんな白目でしたよね。*4
lambda { |n| n ** 2 } # こんなん
最終的には「イテレータの中身を順次受け取る変数」みたいな理解をしましたが、さて、結局勉強会の中ではこの変数を何と呼ぶのか、名前が出てきませんでした。
名前が無いものを覚えるのはちょっと難しいので、名前を探してみましたよっと。
自分で定義したブロック付きメソッドでブロックを呼び出すときに使います。 yield に渡された値はブロック記法において | と | の間にはさまれた 変数(ブロックパラメータ)に代入されます。
メソッド呼び出し(super・ブロック付き・yield
ブロックパラメータというらしいです。
よし、これで覚えやすくなった(気がする)。
その他気づいて調べたこと
Rubyには、演算子扱いされているが実はメソッドだったりする演算子がある
プログラミングの利便のために一部のメソッド呼び出しと制御構造は演算子形 式をとります。Rubyには以下にあげる演算子があります。
演算子式
「Rubyは演算子オーバーロードができる」という話を聞いて、「あれ、それってScalaと同じじゃん? ってことは?」と思ってirbを叩いてみました。
1.+(2) #=> 3
なるほどできた。
ついでにもう一つ。
1.methods # => [:to_s, :-@, :+, :-, :*, :/, :div, :%, :modulo, :divmod, :fdiv, :**, :abs, :magnitude, :==, :===, :<=>, :>, :>=, :<, :<=, :~, :&, :|, :^, :[], :<<, :>>, :to_f, :size, :zero?, :odd?, :even?, :succ, :integer?, :upto, :downto, :times, :next, :pred, :chr, :ord, :to_i, :to_int, :floor, :ceil, :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator, :denominator, :to_r, :rationalize, :singleton_method_added, :coerce, :i, :+@, :eql?, :quo, :remainder, :real?, :nonzero?, :step, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase, :rectangular, :rect, :polar, :conjugate, :conj, :between?, :nil?, :=~, :!~, :hash, :class, :singleton_class, :clone, :dup, :initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :inspect, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :respond_to_missing?, :extend, :display, :method, :public_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
うん、四則演算の演算子やらなんやらが、メソッドとして定義されているようですね。
このへん、ググっても決定的なのが出て来なかったんだけど、以下の2つのルールがシンタックスシュガーとして設定されていそう。
誰か実際のところどうなのか教えてください。