lispとrubyとpythonと(ruby) ver2

rubyも復習がてら昔のエントリを更新。
ちょっとだけ追記した。

# -*- coding: utf-8 -*-
#コメント

#標準出力に表示
puts "こんにちは"
#->こんにちは

# #改行は\n
puts "こんにちは\n"
#->こんにちは
#  

#タブは\t
puts "こんにちは\tこんにちは"
#->こんにちは こんにちは

#フォーマット
#cのprintfと一緒
printf "こんにちは%s\n","世界"

#文字列でフォーマット
#cのsprintfと大体一緒
str = sprintf "こんにちは%s\n","世界"
printf str

puts "aaa %s bbb %s" % ["",""]
#->aaa あ bbb い

#文字列中の式展開
i = 10
puts "こんにちは #{1 + i} 世界"

#バッククオートでくくるとコマンド実行して文字列を返す
puts `date`
#->2008年 12月  7日 日曜日 23:46:46 JST

#関数定義
def fun0 msg
  printf "「%s」を引数としてfunが呼ばれた\n", msg
end
fun0("あいうえお")
#->「あいうえお」を引数としてfunが呼ばれた

#条件分岐
def fun1(n)
  if n < 10 
    printf "10未満\n"

    #elsifなんだそうだ
  elsif n == 10
    printf "10\n"
  else
    printf "10以上\n"
  end
end
fun1(5)
#->10未満

#こんな感じの方がRubyっぽい?
#ぶら下がりif文書くよりも気持ちがいい。
def fun2 n
  printf "10未満\n" if n < 10
end
fun2 5
#->10未満

def fun3 n
  printf "10以上\n" unless n < 10
end
fun3 11
#->10以上

def fun4 n
  case n
  when 0
    printf "0です\n"
  when 1..4
    printf "5未満です\n"
  when 5
    printf "5です\n"
  else
    printf "その他\n"
  end
end
fun4 6
#->10以上

#繰り返し
def fun4 n
  for i in Range.new(0,n)
    printf "fun4 繰り返し%s回目\n", i
  end
end
fun4(3)
#->fun4 繰り返し0回目
#  fun4 繰り返し1回目
#  fun4 繰り返し2回目
#  fun4 繰り返し3回目

##最近は繰り返しの書き方が色々あってそれもどうなんだろう
def fun5 n
  Range.new(0,n).each do |i|
    printf "fun5 繰り返し%s回目\n", i
  end
end
fun5(3)
#->fun5 繰り返し0回目
#  fun5 繰り返し1回目
#  fun5 繰り返し2回目
#  fun5 繰り返し3回目

##whileもある
def fun6 n
  i = 0
  while i < n
    printf "fun6 繰り返し%s回目\n", i
    i = i + 1
  end
end
fun6 3
#->fun6 繰り返し0回目
#  fun6 繰り返し1回目
#  fun6 繰り返し2回目

def fun7 n
  i = 0
  begin
    printf "fun7 繰り返し%s回目\n", i
    i = i + 1
  end while i < n
end
fun7 3
#->fun7 繰り返し0回目
#  fun7 繰り返し1回目
#  fun7 繰り返し2回目

##untilもある
def fun8 n
  i = 0
  until i > n
    printf "fun8 繰り返し%s回目\n", i
    i = i + 1
  end
end
fun8 3
#->fun8 繰り返し0回目
#  fun8 繰り返し1回目
#  fun8 繰り返し2回目
#  fun8 繰り返し3回目

def fun9 n
  i = 0
  begin
    printf "fun9 繰り返し%s回目\n", i
    i = i + 1
  end until i > n
end
fun9 3
#->fun9 繰り返し0回目
#  fun9 繰り返し1回目
#  fun9 繰り返し2回目
#  fun9 繰り返し3回目

#定数定義
CONST_VALUE = "定数\n"
##全部大文字だと定数
##再代入すると警告。警告だけなのか。。。
##CONST_VALUE = "ss"
printf CONST_VALUE
#->定数

#変数
##小文字か_で始まるのはローカル変数
a = 0
##変数のエクステントはスコープが切れるまで
##だけど、クロージャになってたらクロージャが消えるまで有効
2.times do
  p defined?(v)
  v = 1
  p v
end

##グローバル変数
##$で始める
$global_value = "あいうえお"
puts $global_value
#->あいうえお

#クラス定義
#インスタンス変数は@
class Cls0
  #コンストラクタはinitialize
  def initialize val0,val1
    @slot0 = val0
    @slot1 = val1
  end

  def disp
    printf "Cls0 %s:%s\n" , @slot0,@slot1
  end    
end

#継承
class Cls1 < Cls0
  def initialize val0,val1,val2
    #スーパークラスのinitializeを呼び出し
    super val0,val1
    @slot2 = val2
  end
  
  def disp
    printf "Cls1 %s:%s:%s\n" , @slot0,@slot1,@slot2
  end    
end

o0 = Cls0.new "初期値0","初期値1"
o0.disp
#->Cls0 初期値0:初期値1

o1 = Cls1.new "初期値0","初期値1","初期値2"
o1.disp
#->Cls1 初期値0:初期値1:初期値2

#ラムダ式その1
f1 = lambda do |s|
  printf s
end

#ラムダ式その2
f2 = lambda {|s|
  printf s
}

#ラムダ式その3
f3 = Proc.new {|s|
  printf s
}

#ラムダ式その4
f4 = ->s { printf s}

#ラムダ式呼び出し1
f1.call("hello\n")
#->hello
f2.call("hello\n")
#->hello
f3.call("hello\n")
#->hello
f4.call("hello\n")
#->hello

#ラムダ式呼び出し2
f1["hello\n"]
#->hello
f2["hello\n"]
#->hello
f3["hello\n"]
#->hello
f4["hello\n"]
#->hello

#ラムダ式呼び出し3
f1.("hello\n")
#->hello
f2.("hello\n")
#->hello
f3.("hello\n")
#->hello
f4.("hello\n")
#->hello

#クロージャ
def makeDecorator prefix,suffix
  lambda do |s|
    prefix + s + suffix
  end
end

d0 = makeDecorator("<",">")
printf (d0.call "html")
#-><html>

#rubyといえばモジュール
#モジュール
#rubyといえばブロックをとる関数
module Mod0
  def withLog
    printf "処理開始\n"
    yield
    printf "処理終了\n"
  end
end

class Cls2 < Cls0
  include Mod0

  def disp
    withLog do
      printf "Cls2 %s:%s\n" , @slot0,@slot1
    end
  end
end

o2 = Cls2.new "",""
o2.disp
#->処理開始
#  Cls2 あ:い
#  処理終了

def f_with_block(a,&body)
  #受け取るとProcになってる
  puts body
  body.("f_with_block:" + a)
end

f_with_block "test" do |s|
  puts s
end
#->f_with_block:test