なんで書いたの?
他言語開発者は、どうしても今までやってきた言語に慣れてしまっているので、
別の言語を使い始めても今までの言語の感覚で扱いがちです。
自分もRuby,RubyOnRailsの勉強を去年から始めましたが、
今までやってきたC++と大きく違うのに、C++の感覚でソースコードを読んでしまっていたので
なかなか理解が進みませんでした。
この記事はそんな自分の経験からRubyを他言語プログラマが触った時に
悩みそうなところを集めてみました。
この記事は、あ、コレもちょっとわかりにくいかな〜と思ったら追加していきます。
対象
- Ruby以外の言語でバリバリ開発していた人
- Railsの技術書読んでもなかなか理解できない人
- ちょっとRubyに興味がある人
- あるあるwwと酒の肴にしたい人
事例
これはなんの型?
Rubyは、動的型言語
なので、実行された時に自動的に型が判定されます。
また、Rubyはすべてオブジェクト
なので、すべての情報は必ず何らかのクラスです。
例えば、C言語は
int foo=0;
となりますが、Rubyでは、
foo=0
となります。
ここで、なんの型を考えるときは、代入するリテラル
を見ます。
例えば、10なら整数型(Fixnumクラス)、"10"なら文字列型(Stringクラス)と判断できます。
""
や''
で囲まれていない文字列は、文字列としてみなされず、変数
として判断されます。(コレは他の言語でも同じですね)
つまり代入です。
foo = "bar"
baz = foo
もし、fooという変数がなければ、NameErrorが発生します。
baz = foo #=>NameError: undefined local variable or method `foo' for main:Object
Rubyの型で気をつけるべきことは、再代入
を避けることです。
例えば、整数を代入した後文字列を代入してしまうと、ソースの最初を読んだ時に
「お、この変数は◯◯型だな」と思っても、最後のほうで「あれ・・・文字列・・・アレ?」となって、
「どーなってんだこのコードは!」と泣きたくなります。
これはメソッド?変数?
Rubyでは、色々なものが省略可能となっています。
その1つに、メソッドの引数を囲う()を省略可能
という機能があります。
そのため、変数とメソッドをパット見で見分けにくいことが有ります。
例えば、
foo = bar
foo bar
で、前者はfoo変数にbarの値を代入、
後者はfooメソッドの引数にbarを設定となります。
Railsの参考書では、よく()
が省略されるため、変数なのかメソッドなのかをまずちゃんと考えるのが大切だと思います。
例えば、バリデーションを行うvaliates
ですが、
validates :name, :email, presence: true
コレは、
validates( :name, :email, presence: true)
と解釈できます。
慣れてくると、()
がないコーディング、すごく快適だなぁと気づいてきます。
これがRubyのエレガントさ
なのね!と気づきます。
シンボルってなんだよ
シンボルとはなんぞや。
正直散々シンボルを使ってきた今でも他の言語の感覚で説明できません。
イメージとしては、ソース上で意味のある名前の文字列
という感じです。
例えば、ハッシュのキー、メソッド名、クラス名等です。
逆に、文字列の内容などはシンボルでは有りません。
Railsでのシンボルは、各メソッドのオプションで使ったり、メソッドを他のメソッドに渡すときに使ったりします。
Railsはデータベースの各フィールド、オプション引数等でシンボルを多用することになるので、何回も使っていれば感覚的にわかってくると思います。
foo: :bar? :がお見合いしてる?
自分は、コレを最初見た時にえーと・・・?と戸惑いました。
たとえば、リソースの削除を行うdelete
アクションを呼び出す時です。
<%= link_to "削除" :user, method: :delete %>
コレ、説明してしまえば、ハッシュの値にシンボルを指定
しているんです。
つまり、下のような感じです。
hash = {foo: :bar} #=> {:test=>:aaa}
えー、でも{}
はなかったよ?と疑問を持った方。
Rubyでは、{}
も省略できるんです!
と言っても特定条件があって、メソッドの最後の引数のハッシュのみ省略可
という制限があります。
Railsの各メソッドのオプションは、たいてい(全部?)引数の最後にハッシュで渡すオプションがあるため、
{}
を省略してキーをシンボルで指定、値をシンボルで渡す、という風にコーディングすることが多いです。
なので、foo: :bar
という風に:がお見合いしたコーディングになることはよくあります。
具体的には以下の様な形になっています。
def foo(bar, options={})
if options.include?(:baz)
options[:baz]
else
bar
end
foo "bar" #=> "bar"
foo "bar", {:baz=>:baz} #=> :baz
foo "bar", {baz: :baz} #=> :baz
foo "bar", baz: :baz #=> :baz
コレもRubyのエレガントさ
の1つだと個人的に思ってます。
けっこう{}
って打つの面倒臭いですよ・・・ね?
まとめ
ある程度経験してきたプログラマなら、ほとんど触ったことがない言語でも、ある程度コードは読めるものだと思っています。
が、それぞれの言語の特徴をしっかり使ったコードはそれなりに理解に時間がかかるものだ、とRubyを触り始めてから気づいてきました。
特に、CやC++などの言語から、Rubyを始めると、最初は「え、こんなんでいいの?大丈夫なの?」と戸惑うことも多いと思います。
ですが、様々な言語を知ることで、自分のメインとする言語でも「◯◯言語にあるあの機能とか輸入できたら使いやすくならないかな〜」とか考えることができるようになり、視野が広がると思います。
自分もまだまだRuby初学者なので、この記事に対するツッコミ・指摘等どんどんください!
#その他
見なおして不要になった箇所の指摘事項があったので、備忘として残します。
また、変数名、メソッド名は半角英数小文字
という制約があります。
変数名、メソッド名に非ASCII文字(日本語、漢字、カナなど)も使えます。