引子
刷了codecademy的ruby基础,简单做了笔记。
记住两句话:
**Almost Everything in Ruby is an Object. **[except block]
Every operation in Ruby is a method call.
正文
基础概念
- data Types: Numbers, Strings, Booleans
- Puts and print:
- Print 输出不换行
- puts 输出换行
- Comments in Ruby
- Single-line : use # sign for comment in Ruby
- Multi-line :
=begin 略 =end
- getting input
gets.chomp
:variable_name = gets.chomp
gets
is the ruby method that gets input from the user. When getting input, Ruby automatically adds a blank line (or newline) after each bit of input.chomp
removes that extra line.
Control Flow in Ruby
- If … elsif…else…end
- Unless : use control flow to check if something is false.
- Comparators operators, like ==,!=,<, >and so on.
- Logical operators: and(&&), or(||) , not(!)
- As a general rule, Ruby methods that end with ? evaluate to the boolean values true or false. For example , .include?method
字符替换方法:.gsub!
,(global substitution) 通常method后面加上!的表示对这个变量本身做修改,如果没有!,则是复制了该变量,在复制的变量上做了更改。
Loops & Iterators
- while ,until, for
- for中,当有三个.时,比如for num in 1…10, 循环9次,不包括10,当有两个.时,比如for num in 1..10,循环10次,包括10
- break退出循环,例如:
```Rubyi = 20 loop do i -= 1 print "#{i}" break if i <= 0 end ```
- Next! 用于跳过一些步骤,例如:
```Rubyfor i in 1..5 next if i % 2 == 0 print i end ```
- .each iterator
- .times iterator
Data Structure: Array and Hashes
Array: index from 0
Hashes: sort of like JavaScript objects or Python dictionaries, is a collection of key-value pairs
hash = { key1 => value1, key2 => value2, key3 => value3 }
Hash.new 会新建一个空的hash,类似于生成了一个空的{}
可以给一个hash附上默认值,但是hash仍是空的表,当你访问一个不存在的key时,会返回这个默认值。例如:
h = hash.new("nothing") puts h # {} puts h["kitty"] # nothing
遍历hash,使用.each:
pets = { "dog" => 12 "cat" => 12 "mouse" => 3 } pets.each {|pet, age| puts "#{pet} : #{age}"}
Methods and Sorting
method
- 当不清楚需要传递的参数有多少个的时候,用*, 即splat arguments。如: name可以是一个string,也可以是一组字符串数组
```Ruby def friend(*name) puts "my friend(s) " + name end ```
- 当不清楚需要传递的参数有多少个的时候,用*, 即splat arguments。如: name可以是一个string,也可以是一组字符串数组
sort
- .sort!, 也可以自定义排序,默认是升序,例如:
<=>是比较符号,例如:a<=>b,如果a > b, 1 ; a == b ,0 ; a < b, -1.```Ruby books.sort! do |firstbook, secondbook| firstbook <=> secondbook end ```
- .sort!, 也可以自定义排序,默认是升序,例如:
hashes and Symbols
symbol : a ruby symbol is like a sort of name,but it is not a string.
Symbol vs string : while there can be multiple different strings that all have the same value, there’s only one copy of any particular symbol at a given time.
Symbol 总是以:开始,以字母或_为首字符。
Symbol 大量出现在hash keys 或者referencing method names中, symbol作为hash keys的优势:
- 不可更改:They’re immutable, meaning they can’t be changed once they’re created;
- 节省内存:Only one copy of any symbol exists at a given time, so they save memory;
- 快于字符:Symbol-as-keys are faster than strings-as-keys because of the above two reasons.
symbol 与string可以相互转化:
.to_s
and.to_sym
or.intern
用
.select
来对hash进行筛选。如:```Ruby grades = { alice: 100, bob: 92, chris: 95, dave: 97 } grades.select {|name, grade| grade > 97} # ==> {:alice => 100} grades.select {|k,v| k == :chris} # ==> {:chris => 95} ```
.each_key
,.each_value
, 可以单独访问hash的key 和value
The Zen of Ruby
simple, productive
a simpler ‘if’ : such as expression if boolean
One-line Unless : such as expression unless boolean
Ternary : boolean ? Do this if true: do this if false. For example: puts 3<4?”3 is smaller than 4”: “3 is bigger than 4”
the case statement:
case language when "JS" then puts "Websites" when "Python" then puts "Science" when "Ruby" then puts "Web apps" else puts "I don't know" end
conditional assignment: ||=
return in ruby: 在ruby中,如果没有指明return,它的methods会默认return最后一个有值的表达式。
only false and nil are false value in Ruby.
.upto
,.downto
methods. for example:```Ruby "L".upto("P") {|word| puts word} # L # M # N # O # P ```
.respond_to? : takes a symbol
and return true if an object can receive that method and false otherwise.[1,2,3].respond_to?(:push) # true 这里因为数组是有push这个method的,所以是true [1,2,3].respond_to?(:to_sym) # false to_sym不能针对整个数组进行操作,所以是false
.push
or<< :
add an element to the end of a array / string
Blocks, Procs, and Lambdas
Blocks : it is not a object. this is one of the very few exceptions to the “everything is an object” rule in Ruby.
block can be combined with methods like
.each
and.times
to execute an instruction for each element in a collection (like a hash or array).5.times {puts "I'm a block!"}
.collect
can also use to take a block:.collect
returns a copy of my_nums, but doesn’t change (or mutate) the original my_numsarray. use.collect!
to change the array.```Ruby my_nums = [1,2,3] my_nums.collect { |num| num**2 } my_nums # ==> [1,2,3] my_nums.collect! { |num| num**2 } my_nums # ==> [1,4,9] ```
yield
, methods accept blocks using the yieldkeyword. for example:```Ruby def yield_name(name) puts "In the method! Let's yield." yield("Kim") puts "In between the yields!" yield(name) puts "Block complete! Back in the method." end yield_name("Eric") { |n| puts "My name is #{n}." } ``` 输出结果: In the method! Let's yield. My name is Kim. In between the yields! My name is Eric. Block complete! Back in the method.
定义一个double函数,使用yield + block 的方式(不在函数里面定义,而是用block的方式去定义)
```Ruby def double(number) yield(number) end double(2){|n| n*2} ```
Proc : “saved” block. Procs are great for keeping your code DRY, which stands for Don’t Repeat Yourself.
- just call
Proc.new
and pass in the block you want to save. e.x.cube = Proc.new {|x| x**3}
- Usage:
The & is used to convert the cubeproc into a block.[1,2,3].collect!(&cube) [4,5,6].map!(&cube)
- why Procs?
- 是个对象:Procs are full-fledged objects, so they have all the powers and abilities of objects. (Blocks do not.)
- 反复使用:Unlike blocks, procs can be called over and over without rewriting them.
.call
可以直接call procs .```Ruby test = Proc.new {puts "hello"} test.call # ==> hello ```
- Symbol, meet proc
```Ruby string = ["1","2","3"] nums = strings.map(&:to_i) # ==> [1,2,3] # By mapping &:to_i over every element of strings, we turned each string into an integer ```
- just call
Lambda
- Syntax :
lambda {|param| block }
- Lambda VS Proc (super similar)
- a lambda checks the number of arguments passed to it, while a proc does not. This means that a lambda will throw an error if you pass it the wrong number of arguments, whereas a proc will ignore unexpected arguments and assign nil to any that are missing.
- when a lambda returns, it passes control back to the calling method; when a proc returns, it does so immediately, without going back to the calling method.**
- Syntax :
Object-Oriented Programming
class : a way of organizing and producing objects with similar attributes and methods.
@var : an instance variable, means the var is attached to the instance of the class.
Scope : The scope of a variable is the context in which it’s visible to the program.
@@var : an class variable, belongs to the class itself.
$var : global variable
Inheritance Syntax :
```Ruby class DerivedClass < BaseClass # some stuff end ```
Override: 在子对象中定义了与父对象一样的方法时,会自动覆盖掉父对象的方法
super, 当需要在子对象调用被覆盖的父对象方法时,用super,例如:
```Ruby class Creature def fight return "Punch to the chops!" end end class Dragon < Creature def fight puts "Instead of breathing fire..." super end end ```
只能继承一个父类 :Only One!
attr_reader, attr_writer: you can read and update a particular variable. or just use attr_accessor to make a variable readable and writeable in one fell swoop.
```Ruby class Person attr_reader :name attr_accessor :job def initialize(name, job) @name = name @job = job end end ```
Module: being very much like classes, but modules can’t create instances and can’t have subclasses. They’re just used to store things!
- Ruby constants are written in ALL_CAPS and are separated with underscores if there’s more than one word.
- One of the main purposes of modules is to separate methods and constants into named spaces. This is called (conveniently enough) namespacing
- include mixes a module’s methods in at the instance level (allowing instances of a particular class to use the methods)
- extend mixes a module’s methods at the class level.
不论class还是module,命名都是以大写字母开头,纯字母构成,没有数字和下横线_