2015年12月25日 星期五

模糊關係矩陣的合成 in scilab

// 模糊關係矩陣的合成 in scilab
// 用法例: fuzzycompo(R,S)   => 此函式輸出的模糊關係矩陣 是R,S兩模糊關係矩陣的合成

function C=fuzzycompo(A, B)
  [nrA ncA] = size(A)
  [nrB ncB] = size(B)
  // ncA與nrB須相等, 若想檢查則加scripts於此處
  C=zeros(nrA,ncB);
  for i=1:nrA
    for j=1:ncB
      [minV] = min(A(i,:), B(:,j)');
      [C(i,j)] = max(minV);
    end
  end
endfunction

// 網上或有現成, 但找一會兒没找到就自己寫了

2015年12月11日 星期五

未來

昨與母親大人聊天, 她聽人說未來北京會變成沙漠。
我拿荷蘭與地球暖化例子反駁這個可能:
"人類欲望無止盡, 除非有科技替代, 否則減緩暖化應不可能,
 但像新聞說的那樣預言一堆城市百年後會變成海我也不相信,
 未來應該是海平面愈高, 防洪堤愈高"
凌晨看大愛二台的地球證詞重播正巧講防洪

從節目中看到荷籣電腦控制的防洪堤與抽水機,
我想未來應該會有某種柰米塗料漆在防洪堤靠陸地那面,
利用毛細管原理將接觸防洪堤的水往上引, 防洪堤上端像外面傾斜,
故能引導上端的水會再因地心引力傾流入海
雖只能部份替代抽水,
即使這様荷蘭抽水機的幾十年節省電費也會滿可觀

再看到荷蘭的水陸兩棲屋, 屋背後有中軸, 屋隨水高低而上下
但因電線長度等限制只能提高5公尺,
我想未來可能將中軸作的很高很高,
最上端會有電源收發器, 以微波或雷射來傳送能源,
(能精確判斷傳送位置, 通訊是類似p2p或蜂巢或更先進的傳送)
兩棲屋中有充電電池, 類似現在的充電汽車,
屋中能源皆用自電池, 屋自有檢測電源儲備量裝置,
當覺得想要有充電時, 兩棲屋會自動發送訊息給電廠中的電腦,
電廠再以微波或電射方式傳送能源至兩棲屋

未來即使像凱文科斯納的水世界那樣,
電廠也可設在高山上, 例如喜瑪拉雅山,
太陽能電池放在人造衛星或雲端上的無人飛行器上,
以微波或雷射來傳送強大能源給山上電廠, 山上電廠再分送給兩棲屋
甚或有兩棲屋建造船, 以3D列印方式建造兩棲屋
所以即使最悲觀的水世界, 亦不至像電影那様, 而仍會是個文明世界

過去超級火山爆發而史前人類都還有兩三千人能存活下來,
現代人的手段很多, 不可能不如原始人
地球外的不論, 地球內的東東我想只有 地球人 才能滅絕地球人

2015年7月30日 星期四

stagefright 號稱95%的Android手機都有的漏洞


stagefright-exploit
號稱95%的Android手機都有的漏洞
真正根本補洞的方式是要更新韌體
若要DIY則須從廠商處得到最新韌體(先確定廠商有提供)
待root機過後再來更新韌體...粉麻煩...
(注意!!! 自行更新韌體有死機風險!)
root機後亦最好解除root, 因root機面對此漏洞的風險更大 <ref.2>

漏洞發現者Joshua Drake將於2015/8/5美國黑帽大會上詳細講解此漏洞


中文:
ref.1 https://zh.wikipedia.org/wiki/Stagefright%E6%BC%8F%E6%B4%9E
ref.2 http://tech.qq.com/a/20150727/055160.htm


底下是原文

簡易保護方式:(其實漏洞仍在, 只是不要去觸發它...)
ref.3 http://www.cbsnews.com/news/android-stagefright-flaw-protect-android-phone/

技術相關參考:
ref.4 https://www.twilio.com/blog/2015/07/how-to-protect-your-android-device-from-stagefright-exploit.html
ref.5 http://www.dshield.org/diary.html?date=2015-07-28
ref.6 http://www.androidcentral.com/stagefright-exploit-what-you-need-know

相關新聞串:
https://news.google.com/news/story?ncl=dwQAYkiOH634R6MAB-J4wtJAj2ACM&q=vulnerabilities&lr=Chinese&hl=en&sa=X&ved=0CCgQqgIwA2oVChMIgJyu6oyCxwIVp9mmCh1O4QkR

2015年7月28日 星期二

周星星的超能衣

周爺電影中毒太深, 底下是今早作的夢:


將起黎明尙未至, 陰風陣陣, 達聞西-凌凌漆的發明博士 發明了"周星星超能衣", 發給後方將赴戰場的超能部隊裡每人一件

"真是太神了" 周星星拿起超能衣說道

"上了戰場才能穿" 發明博士達聞西廣播提醒

"那還等什麼" 超能部隊裡每人都等不及地將它穿起, 穿後跳飛 "衝啊"

"不行啊! 環保衣太陽能發電! 現在還没太陽, 裡面只有幾秒能源"  發明博士趕緊說

"什麼" 已跳飛的周星星往下回望

"不用怕, 我們用特異功能支援" 食神火雞姊帶頭衝的先鋒部隊成員齊喊, 紛紛用起移動相關的超能力

不用則已, 没想到, 一用反而更亂

JUMP 瞬間移動者載不動那麼多人的能量, 呈現不規則的分身現象, 使得一些部隊成員開始被撞飛

現場開始出現龍捲風, 一些人被捲進風內

"啊! 上了科學小飛俠的當啦!" 原來先鋒部隊中有成員是科學小飛俠的徒弟

"小日本果然不可信" 旁白説道


然後我就醒了

2015年4月28日 星期二

Ruby , a pure OO language, only supports single inheritance

            此note最初是於寛螢幕下作出的,故宜貼至類似環境下再閱讀較佳

Ruby, a pure OO language, only supports single inheritance.  -- 較適合已有基礎的程設愛好者

執行方式有以下幾種:
I.交談模式 (有些版本不支援此)
ex. hello例:
1. 打ruby進入
2. 打 puts "Hello, world!"           # 註:puts 可簡化成 p
3. 按^D

II.ruby <script檔名>
ex. ruby hello.rb

III. use the Unix ``shebang'' notation as the first line (記得檔名加x屬性)
第一行常用有:
如:#!/usr/bin/ruby -w
或如:#!/usr/bin/env ruby  用此行可避免像上行在不同系統而可能需改path等情形


常量亦為物件,故有其method可用,如:
"gin joint".length  為 9
"Rick".index("c")   為 2
-1942.abs           為 1942
若類別或模組內含constant, 平時可用<類別名或模組名>::<CONST名>來讀取
(注意!constant名的開頭字元必須大寫! 例如class名 屬constant, 故第一字元須大寫)

像諸如 number = number.abs 對ruby是合法的,故使用時須小心

true or false:
只有false和nil表示false, 其他皆表為true, 故在Ruby中,0亦為true.

字串例:
str = "Tom" + " Huse"           # -> "Tom Huse"
str[-4,1] + str[1,2] + str[-1,1]  # -> "Home"

Control Structures:
如 if ...elsif....else....end
如 while......end
當if...end 中間僅一行時用  ... if ... 亦可(後不含end)
同理 while...end僅一行時可用 ... while ...

Array (containers之一) 建立方式例:
I 法ex. empty1 = []
II法ex. empty2 = Array.new
III法ex.empty3 = Array.new(0) # 0表長度為0, 故empty3亦為一empty array

當puts 一array時,自動地一元素列一行; 若需陣列印於一行,則陣列後須加.inspect
ex.
a = [5, 6, 7, 8, 9]
puts a.inspect             # 印出 [5, 6, 7, 8, 9]

for i in 0...a.length      # 因a只五個元素,故此例a.length為5,注意此行三點... 會不含上限,故i只執行到4 (i.e.5-1);若是二點..才會包含上限至i=5
  puts a[i]                # 陣列a元素一行一個依次印出
end

a.length.times do |i|      # 此三行與上for迴圈效果相同 (執行5 次迴圈,預設從0開始,故只執行到4)
  puts a[i]
end


Regular Expressions:  ( =~ 用法同 Perl )
ex1. /P(erl|ython)/ 相當於 /Perl|Python/
ex2. /\d\d:\d\d:\d\d/     # a time such as 12:34:56
ex3. /Perl\s+Python/      # Perl, one or more spaces, then Python
ex4. /^Ruby (Perl|Python)/ # 開頭依次為為 Ruby, a space, and either Perl or Python
ex5. if line =~ /Perl|Python/
        line.sub(/Perl/, 'Ruby')    # replace first 'Perl' with 'Ruby'
        line.gsub(/Python/, 'Ruby') # replace every 'Python' with 'Ruby'
     end



定義方法:(當定義時,方法內引數若有設值則其值為default)
ex1. 底下 def ... end 之間亦可簡化成一行: return "Test, aug: #{m}"  或 "Test, aug: #{m}"  (因 Ruby可省略 return)
def testFn(m='d-0')
  result = "Test, aug: " + m         # <=> result = "Test, aug: #{m}"
  return result                      # <=> result  (因return 可省略)
end
以下為使用上面testFn方法之同例等價敘述:(皆印出Test, aug: a-1 若不加後面引數則預設'd-0', 那麼將為Test, aug: d-0)
puts testFn "a-1"
puts testFn("a-1")
puts(testFn "a-1")
puts(testFn("a-1"))
由上可知呼叫方法時常可省略括號()

上例之result為一區域變數(變數名開頭亦可底線_)

ex2.
def tstr(_arg1, *rest)     # 除第一引數外,其餘引數在array中,此例將這array命名為rest
  if rest == []            # 判斷rest是否為空
    _arg1   # 當呼叫方法時,只給一引數時的情況會執行至此,此例只是將第一引數return
  else
    "#{rest.join(', ')} and #{_arg1}"      # 多引數時,rest不為空,會執行此行,陣列rest之元素間會以', '來合併, 其後return此合併字串
  end
end

puts tstr("me") # 印出 me
puts tstr("me", "alice") # 印出 alice and me
puts tstr("me", "joe", "tom", "bob") # 印出 joe, tom, bob and me
puts tstr(*["me", "joe", "tom", "bob"]) # *[]表呼叫方法時將陣列中各元素展開後傳至各引數, 結果同上行
puts tstr(*(0..9).to_a) # 類似上行,將0至9展開至各引數,故印出 1, 2, 3, 4, 5, 6, 7, 8, 9 and 0
                                # (0..9) 為一Enumerable例,用其方法to_a => [0 1 2 3 4 5 6 7 8 9],故展開需前頭加*
                                # 此例亦可看出 * 的優先權 比 . 低

當變數前加$者,為全域變數 (ex. $CUSTOMER)
當變數前加@者,為Instance Variables (ex. @X, @_, @pt_3), 其通常用於儲存物件 (如後面OOP中之例)
當變數前加@@者,為Class Variables (ex. @@SN, @@tl)

然而當最前頭為大寫字母時,其為類別名,module名,或常數名(<自>實際上三名皆屬constant) (ex. String, MyClass, PI)
    常數於方法內不可指定也不可更動,一般情況下更動會產生警告
    若成常數參考,reference更動性同上,只要指向同一個referent,referent內容可經由其他參考隨意改變 (例如下面ex.2 中之常數參考C)

ex1. called-by-value 與 called-by-reference
# from: <ref.1>
def addOne(n)
  n += 1          
end
a = 1
puts addOne(a)      # -> 2   # called-by-value
puts a              # -> 1

def downer(string)
  string.downcase!  # 原字串string全轉成小寫,傳回值為nil;若不加'!'則傳回轉小寫之字串內容,但對原字串string並未作任何改變
end
a = "HELLO"
puts downer(a)      # -> "hello"  # called-by-reference
puts a              # -> "hello"

ex2. <ref.1>與上例後面同理,變數自動以reference來處理string,故下面不同的變數都參考同一個string
a = b = C = "wxy"  # 注意 C 為常數reference
b.concat("z")      # => a, b, C 印出結果都為 wxyz (因三者都指向同一個referent)
puts a
puts b
puts C
# 上面三行可用 puts a, b, C 取代,結果相同


blocks:
{...} 或 do ... end 間為 code block. code blocks 可用來實作 callbacks

ex. (而yield處如同替換成其{...}之block,且一yield一block) (下行的方法threeTimes為 Iterator, 詳看下段)
def threeTimes # 此例無引數
  yield # 可用yield召喚block
  yield
  yield
end

threeTimes { puts "The block's here" } # block 的括號 { .. } 可用 do .. end 取代


Iterators:
A Ruby iterator is simply a method that can invoke a block of code repeatedly.
An iterator is a method which accepts a block or a Proc object.  (ref.1)
Iterators are used to produce user-defined control structures--especially loops.
註:Ruby的iterator與C++的有些不同,C++的iterator是物件,用來存取或操縱container中元素;而Ruby的iterator是方法,其內部可視以yield來實作(如 threeTimes例中的threeTimes)
    對C++而言,An iterator is an object that "walks through" a collection....(C++ How To Prog. p.568);就應用上,OOP的iterator都有相近之處

<自> 注意! iterator引數 與 block引數 不見得相同 (依己設而定):
           def 方法後若有(),則其內接的是iterator引數(預設其最後為block, 可用block_given?來判斷實際呼叫時是否有給block)
           而 yield後()內接的是block引數

OOP:
ex. (from ref.1)以類別Person之成員age為鍵值,由小到大來排序(設已有一檔名為 ages 之文件檔,每行格式為 人名: 年齡  e.g. bert:  8)
class Person
  attr_accessor :name, :age         # 因底下def <=>...裡只斟酌age, 故此例就key而言實只需 attr_accessor :age 即可
  def initialize(name, age)
    @name = name
    @age  = age.to_i
  end
  def <=>(other)
    @age <=> other.age
  end
end

people = Array.new # 此行使 people 成一空array (值於下面給定) (注意對Ruby而言Array亦視為一物件)

File.foreach("ages") { |l|             # <自> 此處 File.foreach 為 iterator , 其引數"ages"為文件檔檔名;  而 |l| 為block引數
  people << Person.new($1, $2) if l =~ /(.*):\s+(\d+)/
}
# 上面執行完後,陣列people中每一元素皆為一Person物件

pa = people.sort           # pa 為經排序後之新Array
     # 注意! 上行並未改變原陣列people;若是要更動原陣列則將其換成 people.sort!  那麼將無另一新Array, pa就只是people的reference
     # 由於 sort! 須更改原陣列,故在排序完成前people是frozen的;然而此例sort因建新Array而無需frozen。(此分別對後面的threads很重要)

以receiver來呼叫方法(method), receiver可以是物件,類別,或模組。
比如此例的people.sort的 物件people是receiver, 而 sort 為被reciver呼叫的方法 (the method to be invoked)
呼叫方法省略receiver名時,receiver會預設成self,即當前物件(類似C++的this)。


ex. block_given? 例;  <ref.3>
def takeBlock(p1)    # 此例 p1 為 "no block"
  if block_given?    # 偵測呼叫方法時是否有給 block 若有則至下行,否則到else
    yield(p1)        # 最後一行的iterator呼叫方法會執行到此 => s成為p1 亦即 "no block", 故s.sub(...) 使"no "去掉
  else                  # <自> 注意上行相當於 return s.sub(...) 故return "block"  然而s實際上未變更 (類似 無! 的string.downcase)
    p1
  end
end

puts takeBlock("no block")      # iterator引數 與 block引數 相同例;   沒block => 走else => 印出 no block
puts takeBlock("no block") { |s| s.sub(/no /, '') }      # |s|表使s成為block引數


可將block化為 Proc物件,而當於 Proc物件 前頭加'&' 即為block

ex. (例中dbl 與 square 為 Proc物件;&dbl 與 &square 即成 blocks) <ref.1>
dbl = proc { |i| i+i }
square = proc { |i| i*i }

def mth1(&b) #  mth1方法 亦為一iterator (用來invoke block &b)
  print b.call(9), "\n" # 同理,&b為block 而 b為Proc物件; 故此行 以b為reciever 來呼叫方法call
end # &b 為block ,故mth1方法內若用 block_given?判斷 則會為true

mth1(&dbl)              # -> 18      # 不加()亦可,但會有warning訊息
mth1(&square)           # -> 81


def mth2
  print yield(9), "\n"      # yield()作用與方法mth1中的 b.call()的作用相同,由於此處引數亦為9,故底下mth2()結果亦相同
end

mth2(&dbl)
mth2(&square)

puts( (1..10).collect(&square).join(", ") )    # (1..10)為一Enumerable例,用其方法collect(block)可疊代block回傳結果成一array,
                                               # 故後可用方法join()
                                               # 而印出 1, 4, 9, 16, 25, 36, 49, 64, 81, 100  (注意:collect 亦為 iterator)


一些現成的iterators:

ex. 6.upto(9) { |i|  print i }       # 印出6789 (upto() 為iterator)

ex. 3.times { |i| print i }    # 印出012  (i.e. 執行三次block) (times 為iterator)
ex. ('w'..'z').each  { |j|  print j }       # 印出wxyz   # each is an iterator--a method that invokes a block of code repeatedly
ex. ('w'..'z').each  { |j, k|  print j }    # k為欲傳入的第二引數, 由於此例只傳入第一引數j, 故k為 nil => 仍是印出wxyz



ex. <ref.3>
class TaxCalculator
  def initialize(name, &block)
    @name, @blocktst = name, block   # 平行賦值(parallel assignment), 注意此處將 Instance變數@blocktst 指定為一 Proc物件(其物件名為block)
  end
  def getTax(amount,intr) # <自> 此成員方法內之accept同為物件成員的 @blocktst內之Proc物件
    "#@name on #{amount} and interest #{intr} = #{ @blocktst.call(amount,intr) }"
  end # 注意 Proc物件 於其物件建立時即載入而不是經由getTax呼引而來,故用if block_given? 判別會為false
end

tc = TaxCalculator.new("Sales tax") { |amt, i| amt * i }

puts tc.getTax(100, 0.075)         # 印出 Sales tax on 100 and interest 0.075 = 7.5
puts tc.getTax(250, 0.08)          # 印出 Sales tax on 250 and interest 0.08 = 20.0

上例中的getTax為方法,其receiver為物件tc。
省略方法的括號時,有些Ruby文件會稱其為命令(commands),其本質上仍為方法。比如上例第一個puts行亦可寫成 puts tc.getTax 100, 0.075

<ref.6>
     You might be better off thinking of the block and the method as coroutines, which transfer control back and forth between themselves.
     (<自> coroutines 字典中無此字,co- 有共同,協同之意, 此處應是表明應視block與method為相互協同合作之常式)

雖然Ruby號稱 "Everything is an object". 但精確地說只是 "Almost everything is an object in Ruby".
比如上例的方法getTax()不算物件,但Ruby有Method類別可使上例getTex()封裝成 方法物件(be wrapped in an object)。
如上例之後再接一行 mtd = tc.method(:getTax)   那麼 mtd 才是 方法物件(由上例tc的getTax()封裝而成)。此即為objectify(物件化)
ex. 接上例,下面兩行與上例最後一行結果相同
mtd = tc.method(:getTax)
puts mtd.call 250, 0.08

<自> 雖依照Ruby而言,例中 方法getTax 應亦為iterator (其accept同為物件成員的 @blocktst內之Proc物件)
     然依其他OOP(如C++) 而言, mtd 方為iterator [因 方法物件mtd 才是物件, 而就C++等 iterator是物件(或變數)]


ex. <ref.5>
class A
  def a
    p "blah"
  end
end

class Method # <自> 注意Ruby內建Method類別, 故這裡只算加一成員方法aa於一已存在類別Method
  def aa
    p "hi"
  end
end

f = A.new
f.a # 印出 "blah"
f.method(:a).aa # <自> f.method(:a) 為方法物件,屬於Method類別,故能呼叫上面加入的方法aa, 因而印出"hi"


輸入:
gets為標準輸入,且亦會把輸入值存入$_
ARGF為Ruby提供之已存在物件,表input stream
ex. 印出標準輸入中包含"Test"之行
ARGF.each { |line|    print line  if line=~/Test/ }

General delimited input : %q :Single-quoted string;   %Q, %   :Double-quoted string;    %w :Array of tokens   %x :Shell command
                          %r :Regular expression pattern

ex. 利用 %w 建立一陣列後,其元素為字串,
     下下行會輸出元素 |...|間之animal相當於yield之引數,each為iterator
a = %w{ ant bee cat dog elk }      # 使a成Array, 如 a[2] 為cat
a.each { |animal|   puts animal }  # iterate over the contents

ex. (上例全皆印於同一行而以 -- 分隔)
[ 'ant', 'bee', 'cat', 'dog', 'elk' ].each do |animal|
  print animal, " -- "
end


ex.  Fibonacci <ref.3> <ref.4>
def fibUpTo(max)              # 此亦為 iterator 的實作
  i1, i2 = 1, 1
  while i1 <= max
    yield i1                  # 由此處 i1 知 block 有一引數
    i1, i2 = i2, i1+i2        # 注意!當平行賦值(parallel assignment),等號右邊一律為舊值
  end
end

fibUpTo(100) { |f|   print f, " " }     # 印出 1 1 2 3 5 8 13 21 34 55 89
puts

b=[]
fibUpTo(30) { |val|   b << val }
puts b.inspect                        # 印出 [1, 1, 2, 3, 5, 8, 13, 21]

# 底下六行效果相當於上面 b 三行code;  (由此可看出 Proc物件 不只能當引數,亦可當return結果, 此與一般物件相同)
def into(anArray)                  
  return proc { |val|   anArray << val }
end

fibUpTo 30, &into(a = [])      # 注意 1.陣列變數a 在此處首次出現,故不是區域變數  2. into方法 return一Proc物件, 故into前加&,以適用於 fibUpTo
puts a.inspect                 # 結果與b同,印出 [1, 1, 2, 3, 5, 8, 13, 21]


ex. (改自 <ref.4>)
class Song
  def initialize(title, artist, serialnumber)
    @title, @artistname, @sn = title, artist, serialnumber
  end
  def name
    @title
  end
end

class SongList
  def initialize
    @songs = Array.new
  end
  def append(aSong)
    @songs.push(aSong)
    self     # 回傳當前物件指標; i.e. <=> return self  <=> 相當於 C++ 的 return this;
  end
  def deleteFirst
    @songs.shift
  end
  def deleteLast
    @songs.pop
  end
end

slist = SongList.new        # slist 為一 SongList 物件, 此例其亦為一container

slist.
  append(Song.new('title1', 'artist1', 1)).    # 同一物件連續呼叫方法,可用.來依序連用方法 (好處為物件名只需打一次,看起來較簡潔)
  append(Song.new('title3', 'artist3', 3)).    #   <自> 因於def 成員方法 內最後有用self回傳當前物件指標,故可如此作
  append(Song.new('title2', 'artist2', 2)).
  append(Song.new('title4', 'artist4', 4))

puts slist.inspect

puts slist.deleteLast.inspect      # 'title4'... 之 Song 物件 從陣列中刪除,此行亦用 puts 印出這個被刪除的物件

class SongList
  def [](key)                      # 對SongList類別加建一形式為 [key] 之方法
    return @songs[key]  if key.kind_of?(Integer)          # key 為整數時處理,由於此行下面才能用如 slist[1] 來表其第二元素
    return @songs.find { |aSong|   key == aSong.name }      # find 亦為 iterator,由於此行,下面方可用如 slist['title3'] 方式來存取元素
  end
end

puts slist[1].inspect # 印出 'title3'... 這個 Song 物件
p  slist[0].inspect # 印出 'title1'... 這 Song 物件

p  slist['title3'].inspect      # 此處與 puts slist[1].inspect 結果相同


lambda:
用法幾乎與proc同,甚有文件視兩者同義 (<ref.10> lambda .... Synonym for Kernel::proc)
然兩者還是有些許差異: lambda與proc在處理return時有些許不同,詳例可參考<ref.11>
自己習慣上return通常用於method中而 不在 block/proc/lambda 的裡面使用, 以避免混淆

ex.hello例
testh = lambda { puts "hello" }
testh.call
testa = testh
testa.call



Hash: (containers之一)
ex1. 定義hash例
instSection = {
  'cello'     => 'string',
  'clarinet'  => 'woodwind',
  'trumpet'   => 'brass',
  'drum'      => 'percussion',
  'oboe'      => 'woodwind',
}

p  instSection['oboe']      # 印出 woodwind
p  instSection['cello']         # 印出 string
# 上兩行 <=> p  instSection['oboe'];  p  instSection['cello']       # ';'作用類似C, 但於Ruby中非必須

p  instSection.length           # => 5  因上面有5對
p  instSection.inspect          # 印出 {"oboe"=>"woodwind", ... }  i.e.印出不見得會未按照上面宣告次序(依不同Ruby版本而定)
p  instSection          # 由於只顯示一般字元,不加inspect亦可

# 下行増一element (其為Element Assignment---Associates the value given by aValueObject with the key given by aKeyObject. <ref.7>)
instSection['violin'] = 'string'
p  instSection.length           # => 6  因増一elment故成6對
p  instSection # 印出hash亦證明"violin"=>"string" 増入

p  instSection.keys # hash中所有的keys所組成之array, 故顯示 ["cello", "clarinet", "trumpet", "drum", "oboe", "violin"]
p  instSection.values # hash中所有的values所組成之array, 故顯示 ["string", "woodwind", "brass", "percussion", "woodwind", "string"]

# 下行減一element
p  instSection.delete('oboe') # 刪一element, 回傳所刪除之值, 故此行會印出 "woodwind"
p  instSection.length;   p  instSection     # 顯示 長度成5; hash中變成少了 "oboe"=>"woodwind" 元素
p  instSection['oboe']      # 印出 nil  (表無此元素)

p  instSection.sort # 以key排序後的結果以陣列顯示:[["cello", "string"],......, ["trumpet", "brass"], ["violin", "string"]]
p  instSection # 顯示仍為未排序的hash, 表上行的sort並未影響原來的hash
p  instSection.sort {|a,b|  a[1]<=>b[1]}   # 以value排序(hash中元素:[0]-key; [1]-value), 故顯示如下:
              # [["trumpet", "brass"], ["drum", "percussion"], ["cello", "string"], ["violin", "string"], ["clarinet", "woodwind"]
              # 由上故知 instSection.sort {|a,b|  a[0]<=>b[0]} 與不加block的instSection.sort 兩者結果相同

# 下行淸除hash中所有elements
instSection.clear
p  instSection.length;   p  instSection     # 其亦顯示 長度成0; hash成空{}
p  "empty hash"   if instSection.empty?  # 亦可用.empty?來判斷hash是否為空


ex.2 定義一hash, 其名為testh3, 當指定之key未定義時,將傳回預設值9
testh3 = Hash.new(9)            # 9為我們指定的預設值
testh3['testkey1'] = 3
testh3['testkey5'] = 8
p  testh3['testkey5']           # 印出 8
testh3.replace({ "testkey1" => 300, "testkey5" => 700 }) # 以replace來更改hash中已存在元素
p  testh3['testkey5']           # 印出 700

p  testh3 # 顯示 {"testkey1"=>300, "testkey5"=>700}
testh = { 'testk3' => 60, 'testkey5' => 900 }
testh3.update(testh) # 以上行所建立的hash資料來更新testh3
p  testh3 # 顯示 {"testkey1"=>300, "testkey5"=>900, "testk3"=>60}

p  testh3.has_key?('testkey1')  # 可用 .has_key? 來判斷hash中是否有此key, 因上行之故,此會印出 true
p  testh3['tstkey']             # 由於tstkey未定義,故印出9
p  testh3.has_key?('tstkey')    # 雖有預設值,然實未設定,故印出false


# 當方法的引數當中有hash時,允許省略大括號 { }, 故ex22程式中的兩行程式碼:
# testh = { 'testk3' => 60, 'testkey5' => 900 }
# testh3.update(testh)
# 可以用 testh3.update( 'testk3' => 60, 'testkey5' => 900 ) 來替代



fork 與 thread 的不同:
fork是利用OS去建立子程序,而 thread 是由ruby解譯器實作出來的
故fork較慢,且彼此不分享記憶體空間,其優點在於能暫停等待I/O完成再繼續進行,而thread不行
                                   [ thread 亦會分享global, instance, (thread外部已有的)local var. ] ......(**)
當thread遇deadlock時整個程序都將停止;但thread較快又不會導致thrashing <自註>,且因是由解譯器實作,故即使在DOS下亦能用thread
注意: 每一thread在thread's block內定義的local variables範圍只限於thread自身

ex.
tds = []
for name in ['one', 'two' ] do  # 此迴圈建立兩個threads, 分別命名為one與two
#  tds << Thread.new {        # 下行註解觀點來自於  <ref.8> :
#    localName = name         # 在thread裡面用到name的習慣不好,由於(**)之故, 存取於內可能因其他thread使變數意外被更動 故最好改成下行
   tds << Thread.new(name) { |localName|     # 陣列tds中的元素相當於thread物件,thread中內容為此block, 此例結果陣列tds會有二元素
      a = 0
      3.times do |i|
          Thread.pass       # Invokes the thread scheduler to pass execution to another thread.
          a += i
          print localName, ": ", a, "\n"
      end
   }
end
                           
tds.each {|t|    t.join }    # join 方法確保thread完成前不會結束程式

# 印出結果如下: ( 與<ref.1>略有不同,thread特性使然 )
# two: 0 # i 一開始為0, 故 a+=i 後 a仍然為0
# one: 0
# one: 1 # i 為差分;  a 為和分
# one: 3
# two: 1
# two: 3
#
# <ref.1>所顯示的結果:
# onetwo: : 00
#
# onetwo: : 11
#
# onetwo: : 33
# # <自> 此空行亦為thread中之'\n'所造成



一些thread方法:
Thread.current       # 傳回當前正在跑的thread
Thread.list          # 傳回所有的threads之list
(thead個例).status   # 傳回此thread的狀態: sleep或run ; false表此thread已正常結束 ; nil 表此thread已意外結束(terminated with an exception)




<自註> thrashing 於此應可翻為顛簸

ref.
ref.1 file:///usr/share/doc/ruby*/FAQ.html
ref.2 file:///usr/share/doc/ruby*/ProgrammingRuby-0.4/index.html
ref.3 file:///usr/share/doc/ruby*/ProgrammingRuby-0.4/tut_methods.html
ref.4 file:///usr/share/doc/ruby*/ProgrammingRuby-0.4/tut_containers.html
ref.5 http://stackoverflow.com/questions/529315/how-do-i-get-the-method-object-for-a-method
ref.6 file:///usr/share/doc/ruby*/ProgrammingRuby-0.4/intro.html
ref.7 file:///usr/share/doc/ruby*/ProgrammingRuby-0.4/ref_c_hash.html
ref.8 file:///usr/share/doc/ruby*/ProgrammingRuby-0.4/tut_threads.html
ref.9 https://ruby-china.org/topics/19930
ref.10 file:/usr/share/doc/ruby-*/ProgrammingRuby-0.4/builtins.html
ref.11 http://railsfun.tw/t/method-block-yield-proc-lambda/110


2015年2月23日 星期一

rpm rebuilddb HOWTO

由於/var/lib/rpm/內的db檔Packages壞掉,
如照一般的rebuilddb仍會出錯;須先重置Packages檔方能rebuilddb
主機內的rpmdb是 BerKeley DB 5.2.x 故底下一些開頭有db52_...(from:db52-utils...)須依自己使用的版本更改
執行次序如下:

# cd /var/lib/rpm
# mv Packages Packages-ORIG
# db52_dump Packages-ORIG | db52_load Packages
# /usr/lib/rpm/bin/rpmdbchk  --dbpath=/var/lib/rpm
# db52_recover -ev -h /var/lib/rpm      # <ref.2>
# rpm --rebuilddb -vvv                  # <ref.2>






<ref.0> http://people.redhat.com/berrange/notes/rpmrecovery.html
<ref.1> http://hackthetech.blogspot.com/
<ref.2> http://mandriva.598463.n5.nabble.com/OM-Cooker-PROBLEM-WITH-RPM-DB-td5713309.html
<ref.3> /usr/share/doc/db52_recover/db_recover.html