2013年12月19日木曜日

初めて買ったRubyの書籍がパーフェクトRubyな話。

パーフェクトRubyアドベントカレンダーの19日目です。

正直にお話しします。まだ、あまり読んでいません。


すいません、すいません。
パラパラめくったりはしていますが、他の本を読んでいる微妙なタイミングで買ってしまったのと、今の所Rubyのリファレンスマニュアルを見たりとか、rubyで書かれたコードとかを読みながら、小さなプログラムを組んでいる程度なのでちゃんと読めていないです。手元にあるのにもかかわらず、どこから読んでいいのかわからないという、頓珍漢な答えをしてしまうくらいです。
どこから読もうと思っているのかは、ちゃんとあるので最後の方に書くつもりです。

今、普段書いているのはActionScript3.0 ですが、作業用の補助ツールとかに好んで書いているのはRubyだったりします。

他にもいろいろな書籍があるのに、

「正直にお話しして、まだあまり読んでいないのに何故パーフェクトRubyを最初に選んだか」


という話をします。理由は3つあります。3っつ合わさってこその決め手です。


1. Rubyだから


 もともとフロントエンドで仕事をしていて、ActionScript3.0やJavaScriptを書いていたのですが、どちらもツールとして使うのには扱いづらく、いろいろと他の言語を試してみたりしてました。最初はPHP、次に触ったのはPythonでした。そして、その次に触ってみたのがRubyでした。(※1)
 なんとなく今はRubyがしっくりきている気がしているので、Rubyを使っています。

2. パーフェクトシリーズだから


 PHPを勉強していた時にパーフェクトPHPを買いました。Androidの仕事をした時にパーフェクトJavaを買いました。PHPはあまり使う機会はなかったですが、パーフェクトPHPはフレームワークを作る所の章が今でも参考になっていて、パーフェクトJavaは実際に書く機会があったこともあってとても参考になりました。( ※2 )

3. 読んでみたいと思ったから


 実はプログラマとして最初に触れた自分以外の書いたコードが著者の一人の@sugamasaoさんの書いたコードでした。また最初に一緒にコードを書いたのも@sugamasaoさんでした。学生時代に少しコードを書いていたとはいえ、一人でずっと書いていたこともあって、もう4年前ですが、今でもどういった処理で、どういう目的で書かれていたということをなんとなく思い出せるくらい、とても学んだことがたくさんありました。(自分の書いたコードはすぐ忘れるのに! )

 そういったこともあって、仕事とはあまり関係ないコードで最初にレビューを個人的にお願いしてみたのも@sugamasaoさんだったりします。

 そんな方が共著で一部を書いているRubyの本である。。。。。。あとはわかりますね?


まとめ


 そんなこんなで、買わないわけにはいかない!とおもって、勢いで買ったパーフェクトRubyですが、実はまだちゃんと読めていません。買った理由が完全に個人の経験に依存した理由で、他の方の参考になる気がしません。他の方が参考になる所を書いてくださっているので、自分もそれを参考にしつつ読んでいくつもりです。

 とここまで書きましたが、自分が読もうとしている所は決まっていて、今ちょっとずつサーバーサイドのことを学びつつ、ブラウザで使えるツールなんかをWebrickをつかって書いていたりしていて、ちょっといろいろと学びたいことができてきたので、とりあえず週末あたりにTODOツールを作る所からでも手をつけてみようかなと思っています。

Rubyちゃんと使えるようになりたいぞ!

※1 他の言語をdisれるほどつかってないので、ちゃんとした理由はありません。
※2 よく言えば信頼。わるく言えば妄信。

2013年12月13日金曜日

【CoffeeScript】for文の戻り値メモ

CoffeeScriptの関数は明示的にreturnするべき」って言う記事が流れてきて、CoffeeScriptは触った事なかったけどちょっと気になった事があったのでメモ。

「returnを明示的にしないと元の記事だと無駄なコードが出力される」

 って、さっきの記事にはあったんだけど、Rubyとかもreturnを明示しなくても戻り値のある言語だし、わざわざreturnを明示しなくても戻り値がちゃんとあるというのにはちゃんと意味があると思ってて、できればreturnを明示しなくてもちゃんと期待通りの処理が行われる実装や設計にしていくのが好ましいようなきがした。それを意識して書いてあれば、きっと無駄なコードが出力される事もなさそうな気がする。

そこでRubyのコードとちょっと比較してみた。

 まずはCoffeeScriptのコード
(console.logの戻り値がundefinedみたいなようなのでRubyと同じような結果になるようにputsを定義しています)
puts = (v)->
     console.log(v)
     return v
 
sample = ->
  for i in [0,3,5]
    puts(i + 1)
                                                                                                                                                      
result = sample()
console.log(result)
結果はこうなる。
1
4
6
[ 1, 4, 6 ]
次はRubyのコード
def test
    for num in [0,3,5] do
       puts num + 1
    end
end 

result = test
print result
結果はこうなる。
1
4
6
[0, 3, 5]
この二つを比べてみると、CoffeeScriptとRubyの戻り値の評価の方法が違う事がわかった。

Rubyのリファレンスを見てみると、「 for文はローカル変数のスコープに影響を及ぼさない点が 異なるからです。」ってことなので配列の定義をしている所が最後の評価として返ってきているんだと思う。

CoffeeScriptの方は、for文の中で処理された値を配列にいれて返している。何でそうなっているのかはわからないけれど、そういう評価の方法だとわかっていれば、for文でに保存してそれを配列として返すというjsの出力は無駄というわけではない。

さて、元記事にあるように return文を仕込んだ処理が以下のように書いてあったとする。
puts = (v)->
     console.log(v)
     return v

sample = ->
  for i in [0,3,5]
    puts(i + 1)
  return

result = sample()
console.log(result)
そうすると以下のように処理が行われる。
1
4
6
undefined
何かが必ず「返り値」になるっていうのは、何がどのような順番で評価されるかって言う事を意識して実装しないとってことで、それは結構プログラムを書く時に意識していた方がいい事だと思うし、戻り値が違うのはテストを書いていたりするとおかしくないのでむやみやたらにreturnで返すよりも、できるだけreturnを返さないように常に戻り値をいしきしてじっそうするほうがいいきがした。

同じような出力を期待するには下のような感じでもできるけど、結局returnは使ってない。return使わなくてもよけいなものを出力しないってことは多分できて、結局作業をする人の慣れとか、その時どんなプロジェクト上の最適化をしなくちゃいけないかって所で、バランスをとっていく所なんだと思う。なので元記事の「必ずreturn」を書くって言うのも一つの方法なんだろうと思う。

ただ、元々のJavaScriptがイケてないからこそ、「JavaScriptに変換する言語を作ろう」みたいになったはずで、そのために使っているはずなのに、出力されるJavaScriptをみてCoffeeScriptの処理の最適化の方法を考えていくのも何となく悔しい気がするのでした。
puts = (v)->
  console.log(v)
  return v

sample = (list,x=0)->
      puts(list[x])
      sample(list,x+1) if list.length > x + 1

result = sample([0,3,5])
puts result
書き出されたコード
// Generated by CoffeeScript 1.6.3                                                                                                                    
(function() {
  var puts, result, sample;

  puts = function(v) {
    console.log(v);
    return v;
  };

  sample = function(x) {
    var list;
    if (x == null) {
      x = 0;
    }
    list = [0, 3, 5];
    puts(list[x] + 1);
    if (list.length > x + 1) {
      return sample(x + 1);
    }
  }; 
                                                                                                                                                      
  result = sample();
                                                                                                                                                      
  puts(res);
                                                                                                                                                      
}).call(this);

2013年12月4日水曜日

Androidの勉強をしよう。

Androidに興味があると言っておきながら、全然目に見える形でアウトプットが出せていないので、Androidの勉強をしたいと思います。というわけで現状を整理。

今、ActionScript3.0を書いていて、それだけだとこの先どうにもならないとおもっているので、ちゃんとアウトプットもしてきたいですね、という所でAndroid勉強しようとか思ってる。あ、でも一応JavaScriptとかを仕事で書いていたときもありました。

Androidに関して言えば、触るのが初めてという訳ではなくてちょっとだけ仕事で実装した程度、Androidの実装されたコードはたまに読んでいるという程度。ただ、細かいデバイス依存の実装や、バージョン互換性の問題等はわかっていないでよくしらないよ、といったところです。

最初にAndroidを触ったときは、助っ人みたいな形だったので(Java書いた事ないのに!)、早急にコードを扱わなくてはいけなくて、

http://dsas.blog.klab.org/archives/52003951.html
http://blog.kmckk.com/archives/3551546.html
http://itpro.nikkeibp.co.jp/article/COLUMN/20091126/341182/

ここら辺とActivityThread.javaとかActivityManager.javaとかのソースを読みつつ、ActivityやIntentのライフサイクルとかを把握してプロダクトコードと格闘してた。
 まぁ、そんなこんなで興味をもつにはもったのだけど、たまにSDKのコードをあさって読んだりしている程度。

さて、いろいろ見てきた所Binderの仕組みを理解するといろいろと理解が深まりそうなのでそこを勉強してきたいです。とりあえずこの辺から見ていきたいと思います。

http://togetter.com/li/110186
https://www.nds.rub.de/media/attachments/files/2011/10/main.pdf