Learn Ruby The Hard Way
Study Drills:
Exercise 51
After install rerun tool by sudo gem install rerun
, we can rerun our app without stop it, instead, we type this in:
$ rerun 'ruby bin/app.rb'
創建模板
<%= yield%>
means to stop here, run other view, and then come back.
藉由創造模板佈局 views/layout.erb 並加入 <%= yield%>
,我們可以省下在 views/index.erb, views/hello_form.erb內輸入HTML語法的多餘重複工作()
Exercise 46
示範影片使用了 cp -r skeleton apples
複製整個"skeleton" 資料夾並重新命名為"apples"
利用 grep -r "NAME" .
來尋找並列出包含有"NAME"的地方。
grep
The grep utility searches any given input files.
- If you get an error about Test::Unit you'll need to run
gem install 'test-unit'
to install the testing gems you need.
Exercise 43
Object-Oriented Analysis and Design
物件導向分析與設計
- 描述或畫出問題,分析問題,抽出核心 concept
- Create class hierarchy and object map for the concept
- Simply make a list of all the nouns and verbs in your writing and drawings, then write out how they're related.
- 類別層級架構想出來之後,先寫出程式基礎架構(classes, functions),以及測試程式
Exercise 42
170518-
about "class"super
: It automatically forwards the arguments that were passed to the method from which it's called.
super 方法 = 從父類別繼承內;擴充方法的內容
Exercise 40
170509-
- Classes are like blueprints or definitions for creating new mini-modules.
class X < y
"Make a class named X that is-a Y."
("salmon" is-a "fish")
$var
= Global variable 全域變數@var
= instance_variable 實例變數@@var
= class_variable 類變數
var = local variable
170501-yield
:完美理解ruby中的yield的概念
大学里常常发生占位置的现象:头天晚上拿一本书放在课座上,表示位置已经被占了;第二天才来到这个座位上,翻开书正式上课.在这个现象中,“书本”充当了“占位符”的作用。
在Ruby语言中,yield是占位符:先在前面的某部分代码中用yield把位置占着,然后才在后面的某个代码块(block)里真正实现它,从而完成对号入座的过程.
定义find
def find(dir)
Dir.entries(dir).each {|f| yield f} #获得dir目录下的文件名列表;对每个文件名,用yield来处理(至于怎么处理,还不知道,占个位置先^_^)
end
使用find
find(".") do |f| #block开始
puts f #用输出文件名这个语句,真正实现了yield的处理(也可以用任何其他语句)
end #block结束
由此可见,yield属于定义层,属于宣告层,也就是在心里说一句:"这个位置不错,我先用书本占了再说!";而block属于使用层,实现层,也就是最终你坐在了你先前占的位置上,从而真正的实现了对号入座的过程.
最后,请大家不要问我"万一书本被偷了怎么办?"之类的问题,谢谢合作。
170427-
Regular expression > Ivan suggess skip this part for now.
Exercise 36
170427-
- Rules of
If-Statements
1.Every if-statement must have an else.
2.用else
設置錯誤說明並跳出
3.控制 if statement 在兩層以內
4.前後都要空一行
5.若是 boolean 判斷式太複雜,將之移到前面以適合的變數名稱做計算
- Rules of loop
1.只在需要無限迴圈的時候使用
while-loop
2.其他場合都用for-loop
Exercise 35
170426-=~
Ruby's basic pattern-matching operator
170419-
嘗試加入複數條件於選項的 if-statement but failed, i will try again next day.
Exercise 32
170408-
- about for loop in Ruby
在 stackoverflow.com 看到的新招:.each_with_index
['foo', 'bar', 'baz'].each_with_index {|j, i| puts "#{i} #{j}"}
170406-
Loops and Arrays
兩種建立loop的方法:
for number in the_count puts "This is count #{number}" end
但在 Ruby 社群傾向使用
.each
寫法:the_count.each do |number| puts "This is count #{number}" end
或者:
the_count.each {|number| puts "This is count #{number}"}
Arrays can contain different types of objects. For example, the array below contains an Integer, a
ary = [1, "two", 3.0]
數列的用法:
arr = [1, 2, 3, 4] # to create an array arr.push(5) #=> [1, 2, 3, 4, 5] # push "5" to the end of array arr << 6 #=> [1, 2, 3, 4, 5, 6] # 同上 arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6] # unshift will add a new item to the beginning of an array. arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6] # insert an item to an array at any position.
Exercise 31
170405-
Making Decisions
創造了一個文字冒險遊戲!
透過將if-statement
程式碼鑲嵌在另一個if-statement
內, create "nested" decisions,可以創造複數選項。
Exercise 30
170404-
Else and If
如果一個以上的elsif
都是true
,Ruby 也只會執行第一個。
Exercise 29
170404-
if-statement
基本的 if 陳述式+=
= "increment by"
Exercise 28
170404-
Boolean Practice
練習解邏輯運算
Exercise 27
170404-
Memorizing Logic
背誦基本Boolean邏輯運算,我做了 anki 的卡片供背誦練習。
Exercise 26
170403-
練習除錯
Exercise 25
170403-
學習 module 的用法:從irb內調用 module$irb require ./ex25.rb
Exercise 24
170403-
"%Q, %q, %W, %w, %x, %r, %s"用法
還沒搞懂最後一行出現的%s
%d
的用法。
似乎是把後面function return的值call出來, %s
= string
170328-
What are symbols below do for?&&
= and!
= not!=
= 不等於||
= or
- Use
||=
freely to initialize varibles.#Set name to Bohzidar only if nil or false name ||= 'Bohzidar'
e.g.
判斷 result
是否存在:
result = a || "a exists"
等同於:
if defined?(a)
result = a
else
result = "a exists"
end
要注意的是,由於要判斷a是否存在,所以a一定是要宣告過的數值(例如 a = nil),否則會出現undefined local variable錯誤,不像 ||= 的用法不需要事先宣告。
Ternary operator 三元運算子 ?:
e.g.
if a > 10
result = "big"
else
result = "small"
end
以上可以簡化成:
a > 10 ? result = "big" : result = "small"
記得Ruby的原則是DRY (Dont' Repeat Yourself),這種情況我們可以讓他更為縮減:
result = a > 10 ? "big" : "small"
bad
result = if some_condition then something else something_else end
good
result = some_condition ? something : something_else
多重條件判斷
如果我們要判斷以下內容:
if a > 10 result = "big" elsif a > 5 result = "bigger than 5" elsif a > 3 result = "bigger than 3" else result = "small" end
這種情況可以縮減成以下:
result = ("big" if a > 10) || ("bigger than 5" if a > 5) || ("bigger than 3" if a > 3) || "small"
或者把條件放在前面:
result = (a > 10 && "big" or a > 5 && "bigger than 5" or a > 3 && "bigger than 3" or "small")
Exercise 22
170324-
Review all the symbols.
I was trying to make a program "Table_of_Characters.rb"
to deal with this exercise, but things was not going very well...
Exercise 21
170321-
return
在一個function中,回傳數值:
def subtract(a, b)
puts "SUBTRACTING #{a} - #{b}"
return a - b
end
in this case, return the value of a - b when you call subtract
function.
Exercise 18
170130 -
每次在使用 Function 時,檢查此 checklist:
- Did you start your function definition with def?
- Does your function name have only characters and _ (underscore) characters?
- Did you put an open parenthesis ( right after the function name?
- Did you put your arguments after the parenthesis ( separated by commas?
- Did you make each argument unique (meaning no duplicated names)?
- Did you put a close parenthesis ) after the arguments?
- Did you indent all lines of code you want in the function two spaces?
- Did you end your function with end lined up with the def above?
When you run ("use" or "call") a function, check these things:
- Did you call/use/run this function by typing its name?
- Did you put the ( character after the name to run it?
- Did you put the values you want into the parenthesis separated by commas?
- Did you end the function call with a ) character?
- Functions that don't have parameters do not need the () after them, but would it be clearer if you wrote them anyway?
Exercise 17
170130 -
- Find out why you had to write
out_file.close
in the code. f.close is necessary for prevent file descriptor running out. - "You should always close file descriptors after use" - stackoverflow
Exercise 16
170129 -
echo
指令用法:
echo "This is a test." > test.txt
#產出 test.txt, 內容為 "This is a test"
cat test.txt
#顯示test.txt的內容。
170127 -
Here's the list of commands we need to remember:
close
-- closes the file.read
-- reads the contents of the file.readline
-- reads just one line of a text file.truncate
-- Empties the file. Watch out if you care about the file.write('stuff')
-- Writes "stuff" to the file.
Ruby File.open modes and options
Mode | Meaning |
---|---|
"r" | Read-only, starts at beginning of file (default mode). |
"r+" | Read-write, starts at beginning of file. |
"w" | Write-only, truncates existing file to zero length or creates a new file for writing. |
"w+" | Read-write, truncates existing file to zero length or creates a new file for reading and writing. |
"a" | Write-only, starts at end of file if file exists, otherwise creates a new file for writing. |
"a+" | Read-write, starts at end of file if file exists, otherwise creates a new file for reading and writing. |
"b" | Binary file mode (may appear with any of the key letters listed above). Suppresses EOL <-> CRLF conversion on Windows. And sets external encoding to ASCII-8BIT unless explicitly specified. |
"t" | Text file mode (may appear with any of the key letters listed above except "b"). |
e.g. target = open(filename, 'w')
truncate : target.truncate(0)
Exercise 13
170115 -
round method:
use in irb
$3.785.round(2) = 3.79
$3.785 - 2 = 1.7850000000000001
$(3.785-2).round(3) = 1.785
chomp method:
$name = gets.chomp
It removes the terminating newline.
170115 -
Ex13 study drills
Change your script to use $stdin.gets.chomp
everywhere that you have gets.chomp
. You should use $stdin.gets.chomp
from now on since the action gets.chomp
has problems with ARGV
.
在使用ARGV
時,必須用$stdin.get.chomp
取代gets.chomp
才能正常運作。
Exercise 10
170104 -
About single-quote '
and double-quote "
Must escape these quotation mark like this:
"I am 6'2\" tall." # escape double-quote inside string
'I am 6\'2" tall.' # escape single-quote inside string
170102 -
Escape What it does.
\\ Backslash ()
\' Single-quote (')
\" Double-quote (")
\a ASCII bell (BEL)
\b ASCII backspace (BS)
\f ASCII formfeed (FF)
\n ASCII linefeed (LF)
\r ASCII Carriage Return (CR)
\t ASCII Horizontal Tab (TAB)
\uxxxx Character with 16-bit hex value xxxx (Unicode only)
\v ASCII vertical tab (VT)
\ooo Character with octal value ooo
\xhh Character with hex value hh
Exercise 09
170102 -
For somehow my exercise program ex9.rb
has been facing some syntax issue, and I don't know how could it happen cause I'm pretty sure there is no typo.
days = "Mon Tue Wed Thu Fri Sat Sun"
months = "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug"
puts = "Here are the days: #{days}"
puts = "Here are the months: #{months}"
#line5 doesn't work well as expected.
#here in below seems have some syntax errors
puts %q{
There's something going on here.
With the three double-quotes.
We'll able to type as much as we like.
Even 4 lines if we want, or 5, or 6.
}
執行 $ ruby ex9.rb
時無反應,所以我將原本的 ruby 2.2 透過更新 Homebrew
, rvm
升級為 2.4.0-rc1,結果依然無反應。
After I done all the work and research, I tried to copy the code from textbook and... it works!
將教材的code複製下來執行沒問題,過切換視窗交叉檢查才發現原來是這邊打錯:
puts = "Here are the days: #{days}"
puts = "Here are the months: #{months}"
puts
命令後面多了一個 =
!!
此例再次展現出校驗的仔細和耐心有多重要,正好是目前的我所缺少的技能。
Now, everything work perfectly!