2015年1月21日 星期三

ruby初階

常數(constant) 與變數(variable)的差別:
常數是大寫字母開頭,變數不是,內容同樣可被改變。變數又分區域變數(local variable)、全域變數(global variable)($)、實體變數(instance variable)(@)、類別變數(class variable)(@@)。

公開(public)、保護(protected)、私人(private)的差別:
public是所有人都可以直接使用的,private只有內部可以使用,protected內部或繼承於他的可以使用。

類別(claaa) 、模組(module)差別:
模組無法繼承、無法實體化(new);類別可以繼承、實體化(new)

包含(include) 繼承(extend):
包含:先引進,再實體(new),為實體方法;繼承:為類別方法,直接使用方法

邏輯(logic):只有false跟nil是假的,其他皆為真的
流程控制(flow control):
(1)if...elsif..else..end
weather="runny"
if weather=="runny"
 puts "stay at home"
elsif weather=="sunny"
 puts "let's go out"
else
 puts "sleep"
end
結果:stay at home

(2)unless=not if
weather="sunny"
if not weather=="ranny"
 puts "let's go out"
end
相等於
unless weather=="ranny"
 puts "let's go out"
end
結果:let's go out

(3)if modifier
weather="sunny"
if weather=="sunny"
 puts "let's go out"
end
相等於
puts "let's go out" if weather=="sunny"
結果:let's go out

(4)case..when..else..end
age=16
case age
when 0..3
 puts "baby"
when 4..10
 puts "kind"
when 11..18
 puts "child"
else
 puts "adult"
end
結果:child

(5)a=true?'a':'b'
gender="F"
if gender=="F"
 status="you are beautiful"
else
 status="you are handsome"
end
puts status
相等於
gender="F"
status=(gender=="F")?"you are beautiful":"you are handsome"
puts status
結果:you are beautiful

(6)a||'a'
puts $a
$a=$a||10
puts $a
結果(1):nil
結果(2):10


迴圈(loop)
(1)for..in..end
names=["aa","bb","cc","dd"]
for name in names
 puts name
end
結果:aa
            bb
            cc
            dd

(2)while..end
x=0
while x<5
 puts x
 x+=1
end
結果:0
            1
            2
            3
            4

(3)until=not while
x=0
until x>5
 puts x
 x+=1
end
結果:0
      1
            2
            3
            4
            5

y=0
while not y>5
 puts y
 y+=1
end
結果:0
            1
            2
            3
            4
            5

(3)times次數
3.times do
 puts "hello"
end
結果:hello
            hello
            hello

(4)upto(遞增),downto(遞減)
0.upto(3) do |i|
 puts "hi, apple #{i}"
end
5.downto(1) do |i|
 puts "hi, bird #{i}"
end
遞增結果:hi, apple 0
                    hi, apple 1
                    hi, apple 2
                    hi, apple 3
遞減結果:hi, bird 5
                    hi, bird 4
                    hi, bird 3
                    hi, bird 2
                    hi, bird 1

(5)each(一個一個),each_with_index(一個一個,索引值)
names=["aa","bb","cc","dd"]
names.each do |name|
 puts name
end
names.each_with_index do |name,x|
 puts "#{x} #{name}"
end
結果:aa
            bb
            cc
            dd
結果:0 aa
            1 bb
            2 cc
            3 dd
索引是從0開始,若希望從1開始,puts "#{x+1} #{name}"


單行註解:#...
多行註解:=begin..=end

整數除法:10/3=3
小數除法:10/3.0=3.333~或10.0/3=3.333~

單引號' '(%q):速度較快,但不翻譯,直接顯示
雙引號" "(%Q):會翻譯帶入的變數
age=22
puts "my age is #{age}"
puts 'my age is #{age}'
雙引號結果:my age is 22
單引號結果:my age is #{age}

%W;所有值為字串,可替代陣列使用
p:印出結構
f2=%w{aa bb cc}
p f2
---["aa", "bb", "cc"]


練習:
(1)計算字元(characters)和字(words)
part="Hello, today is sunny. Let's go out."
#character
puts part.delete(' ').delete(',').delete('.').delete("'").size
#words
puts part.split(' ').size
字元結果:26
字串結果:7

(2)把字串"abcdef"變成"fedcba"
str ="abcdef"
a_str="abcdef".split('')
puts a_str.join
a_array=[]
while char=a_str.pop
 a_array<<char
 puts a_array.join
end
puts a_array.join
---abcdef
---f
    fe
    fed
    fedc
    fedcb
    fedcba
---fedcba

(3)陣列[1,3,4,1,7,nil,7,5],去nil,重複值,由小到大排列
p [1,3,4,1,7,nil,7,5].compact                    #去nil
p [1,3,4,1,7,nil,7,5].uniq                          #去重複值
p [1,3,4,1,7,nil,7,5].compact.uniq           #去nil、重複值
p [1,3,4,1,7,nil,7,5].compact.sort            #去nil、由小到大排列
p [1,3,4,1,7,nil,7,5].compact.uniq.sort    #去nil、重複值、由小到大排列
結果:[1,3,4,1,7,7,5]
結果:[1,3,4,7,nil,5]
結果:[1,3,4,7,5]
結果:[1,1,3,4,5,7,7]
結果:[1,3,4,5,7]
注意:.sort排序:需先把nil值去掉(.compact),才能進行由小到大排列。

(4)1~52,任五個不重複
#印1~52
p (1..52).to_a
#印隨機1~52
p (1..52).to_a.shuffle
#印隨機1~52的前5個
p (1..52).to_a.shuffle.first(5)
#用sample方法
p (1..52).to_a.sample(5);
結果:[1,2,3,...,52]
結果:[21,17,44,...,15]
結果:[3,40,12,42,2]
結果:[4,16,39,50,45]
.to_a:轉成陣列;
.shuffle:洗牌。


Hash.new,a={}
a={:name=>'apple'}
a={name:'apple'}
p a[:name]
結果:"apple"


範圍range,直接看下面例子
p (1..10).to_a
p (1...10).to_a
---[1,2,3,4,5,6,7,8,9,10]
---[1,2,3,4,5,6,7,8,9]

(1)練習:從1加到100總和
sum=0
(1..100).to_a.each do |x|
 sum+=x
end
puts sum
#inject方法
sun=0
puts (1..100).to_a.inject{|sum,x| sum+x}
---5050
---5050


method,function
def method_name(param)
 ...
end


yield控制權丟出去
def do_something
puts "1"
yield
puts "2"
end
do_something do
puts "hello"
end
答案:1
            hello
            2

my_square=Proc.new{|x|x**2}
puts my_square.call(10)
puts my_square[5]
puts my_square.(15)
puts my_square === 10
結果:100
            25
            225
            100


在ruby中萬物皆物件(everything in Ruby is an Object)
物件(object)=狀態(state)+行為(behavior)


初始化initialize:在new後執行
class Dog
 def initialize
  puts"hello, dog"
 end
end
dog=Dog.new
結果:hello, dog


建立Dog類別和Cat類別,並繼承Animal類別,都實作walk和eat兩方法
class Animal
 def walk
  puts "walking"
 end
 def eat
  puts "eating"
 end
end
class Dog<Animal
end
class Cat<Animal
end
dog=Dog.new
dog.walk
dog.eat
cat=Cat.new
cat.walk
cat.eat
結果:walking    #Dog.walk
            eating       #Dog.eat
            walking    #Cat.walk
            eating       #Cat.eat
<繼承:父擁有的方法,子可以使用若另外設同名的方法會蓋掉父原先的方法

class Dog
 def initialize(name)
  @name=name                        #此為實體變數,若往外在class之下,則為類別變數
 end
 def name                                 #getter
  return @name
 end
 def name=(new_name)          #setter
 return @name=new_name
end
dog=Dog.new('lucky')
puts dog.name
dog.name="kevin"
puts dog.name
結果:lucky         #getter
結果:kevin         #setter


class String
 def say_hello
  "hi, I am #{self}"
 end
end
puts "sunny".say_hello
結果:hi, I am sunny


模組Module
module ModuleName
 ...
end


include和extend的差別,實例如下:
(1)建立繼承自Animal類別的Bird類別,並引入(include)一個fly的模組
module Flyable
 def fly
  puts "I can fly"
 end
end
class Animal
end
class Bird<Animal
 include Flyable
end
bird=Bird.new
bird.fly
---I can fly
類別名字和父類別都要使用常數定義,否則不會過(常數為大寫字母開頭)

(2)建立繼承自Animal類別的cat類別,並用extend一個吃eat的模組
module Eatable
  def eat
    puts "I can eat"
 end
end
class Animal
end
class Cat<Animal
  extend Eatable
end
Cat.eat
---I can eat

include進來後要先實作new,才能使用;extend進來不用實作,可直接使用。

沒有留言:

張貼留言