Ruby-Cheatsheet

安装

ref: Installing Ruby , Download Ruby 在线使用: TryRuby playground Linux: sudo apt-get install ruby-full or sudo yum install ruby macOS: brew install ruby , 也可以参考这里[[M芯片的macOS安装Ruby]] Windows: winget install RubyInstallerTeam.Ruby or RubyInstaller for Windows 可选安装: GitHub - rbenv/rbenv: Manage your app’s Ruby environment RVM: Ruby Version Manager

交互模式

打开终端,输入irb即可进入Ruby交互模式

irb(main):002:0> puts "Hello World"
Hello World
=> nil

变量

myVar = 48

常量

PI = 3.1415

输出

print "Hello"
puts "This is written in a new line"
print "Still printing"
age = 30
print "Hi, my name is Cody, and I am #{age} years old"
# "Hi, my name is Cody, and I am 30 years old"

输入

print "Type your name and press Enter: "
name = gets.chomp
puts "My name is #{name}!"

注释

# I am a single line comment.

=begin I am a multi line comment. I can take as many lines as needed. =end

数据类型

基本

i1 = 1 # Integer value
f1 = 1.2 # Float value
s1 = 'I am a single string!' # String
s2 = "I am a double string!" # String
b1 = true # Boolean
b2 = false # Boolean

字典(Hash)

profile = {
  "name" => "Magnus",
  "ranking" => 1,
  "grandmaster?" => true, # error: "grandmaster?" : true,
  :run => true, # it's a symbol
  language: "Ruby" # it's a symbol, only symbol can use :
}
# {"name"=>"Magnus", "ranking"=>1, "grandmaster?"=>true, :run=>true, :language=>"Ruby"}
puts profile["name"] # => Magnus
puts profile[:run] # => true
puts profile[:language] # => "Ruby"
profile = Hash.new # => {}
profile[:name] = "Messi" # => {:name=>"Messi"}

数组(Array)

numbers = [1, 2, 3, 4, 5]
words = ["See", "Spot", "run"]
mixed = ["hello", 5, true, 3.0]
empty = []
multi_array = [[0,1,2,3],[4.5, true, "hi"]]
multi_array[1][2] # "hi"

引用(Symbol) ruby中,每个对象都有唯一的标识符(object_id),而引用只有一个标识符 ruby中内部操作符和变量其实都是symbol,比如’+’也是一个symbol

:foo # 以 : 开头声明一个引用
p :foo.object_id # 2737308
p :foo.object_id # 2737308
p "foo".object_id # 500
p "foo".object_id # 520

运算符

print 1+3 # Addition: output 4
print 1-2 # Subtraction: output -1
print 9/3 # Division: output 3
print 2*3 # Multiplication: output 6
print 2**3 # Exponentiation: output 8
print 16%9 # Modulo: output 7
num = 12;
num *= 2; # 24
num += 2; # 26
num -= 2; # 24
num /= 4; # 6
a = 1;
b = 2;
puts a > b; # false
puts a < b; # true
puts b >= a; # true
puts a <= b; # true
puts a == 2 || b == 2; # true
puts a == 2 && b == 2; # false
data = true;
print !data # false

组合运算符<=>

puts 1 <=> 2 # -1
puts 1 <=> 1 # 0
puts 2 <=> 1 # 1
puts "A" <=> "B" # -1

条件赋值运算符||= 仅在变量为nil或者false的情况下赋值,否则保持原值

name = nil
name ||= "Tony"
name ||= "Mark"
p name # => "Tony"

push运算符<<

array = [1, 2, 3]
array << 4 # => [1, 2, 3, 4] # 也可以使用array.push(4)
print array #Output => [1, 2, 3, 4]
puts "Hello," << " welcome to Codecademy." # => Hello, welcome to Codecademy.

控制流

if

print "enter a number: "
num = gets.chomp
num =  num.to_i

if num == 5 print “number is 5” elsif num == 10 print “number is 10” else print “number is something other than 5, 10” end

如果没有else,则可用简写

puts “This number is even!” if num % 2 == 0

case

str = "two"
#### 默认形式 ####
case str 
    when "one"  
      puts 'Input is 1'
    when "two","2" 
      puts 'Input is 2'
    when 3..10
      puts '10 >= Input >= 3'
    else  
      puts "Default!"
end
#### 没有case值 #### 使用when来判断,类似if
str = "GeeksforGeeks"
case
    when str.match(/\d/)
          puts 'String contains numbers'
    when str.match(/[a-zA-Z]/)
          puts 'String contains letters'
else
    puts 'String does not contain numbers & letters'
end

三元操作符 : ?

a = 12
puts a>=2 ? "a>=2" : "a<2"

unless: 除非满足条件,否则执行

##########
unless num > 10
  print "number <= 10."
end
# Output: number <= 10.

循环

each

data = [3, 6, 9, 12]
data.each do |num|
  puts "The number is: #{num}"
end
# Output:
# The number is: 3
# The number is: 6
# The number is: 9
# The number is: 12
polygons = {
  "pentagon" => 5,
  "hexagon" => 6,
  "nonagon" => 9
}
polygons.each do |shape, sides|
  puts "A #{shape} has #{sides} sides."
end
#Output
#A pentagon has 5 sides.
#A hexagon has 6 sides.
#A nonagon has 9 sides.

指定范围:

# Inclusive
(3..5).each do |i|
  print i
end
# Output: 345
# Exclusive
(3...5).each do |i|
  puts i
end
# Output: 34 

for, next if: 用在循环中,跳过满足条件的值

for i in 1..10
  next if i % 2 == 0
  print i
end
# Output: 1 3 5 7 9

while

i = 1
while i <= 3 do
  puts "Message number #{i}"
  i = i + 1
end
# Output:
# Message number 1
# Message number 2
# Message number 3

times

5.times { print "Hi" }
# Output: HiHiHiHiHi
2.times { |time|   # '{' == do
  puts time
}    # '}' == end
# 0
# 1

loop, break if

num = 1
loop do # or use {
  puts "We are in the loop!"
  num += 1
  break if num > 3
end # }
puts "We have exited the loop!"
# Output
# We are in the loop!
# We are in the loop!
# We are in the loop!
# We have exited the loop!

until

i = 1
until i == 4 do
  puts "Message number #{i}"
  i = i + 1
end
# Output
# Message number 1
# Message number 2
# Message number 3

函数

#### 无参数 ####
def hi
    puts "Hello World!"
end
hi() # "Hello World!"
hi # "Hello World!"
#### 固定参数 ####
def hi2(name)
    puts "Hello #{name}!"
end
hi2("Tony") # "Hello Tony!"
hi2 "Tony" # "Hello Tony!"
#### 参数默认值 ####
def hi3(name = "World")  # set default value
    puts "Hello #{name.capitalize}!"
end
hi3 # Hello World!
hi3("tony") # "Hello Tony!"
#### 可变参数 ####
def extra_curriculars(p1,*parameters)
  print p1
  parameters.each { |p| print p }
end
extra_curriculars(1, 2, "c", "d") # 12cd
#### 散列参数 ####
def hash_para(options={})
  p options
end
hash_para a:1,a:2 # hash_para({a:1,a:2}) or hash_para(a:1,a:2) but no hash_para {a:1,a:2}
# Output: {:a=>1, :b=>2}
#### 未定义的参数 和 引用参数 ####
def my_m(x:0,y:,**args)
  p x,y,args
end
my_m(x:1,y:2,'a'=>3,'b'=>4) # [1, 2, {"a"=>3, "b"=>4}]
#### 返回值 ####
def product(x,y)
  x * y  # == return x*y
end
#### Other ####
def hungry?(time_of_day_in_hours) # 对于返回值为bool类型的,可添加问号,更可读些。
  puts "Me hungry"
  true   # == return true
end

lambda函数

lambda_test = lambda { puts "I am the lambda method!"}
lambda_test.call # => I am the lambda method!

proc: 对一个代码块的封装

proc_test = Proc.new { puts "I am the proc method!" )
proc_test.call # => I am the proc method!
square = Proc.new { |x| x ** 2 }
square.call(3) # => 9

lambda和proc区别:

def proc_demo_method
  proc_demo = Proc.new { return "Only I print!" }
  proc_demo.call
  "But what about me?" # Never reached
end

puts proc_demo_method

Output: Only I print!

def lambda_demo_method lambda_demo = lambda { return “Will I print?” } lambda_demo.call “Sorry - it’s me that’s printed.” end

puts lambda_demo_method

Output: Sorry - it’s me that’s printed.

lambda_demo调用了,但并没有输出

yield 用于将控制权从一个方法转移到一个块,然后在执行后转移回该方法

def yield_test
  puts "I'm inside the method."
  yield
  puts "I'm also inside the method."
end
yield_test { puts ">>> I'm butting into the method!" }#Output
# I'm inside the method.
# >>> I'm butting into the method.
# I'm also inside the method.

类(class)

class Greeter
    @@count = 0 # 类变量,在不同实例中共享
    def initialize(name = "World")
        @name = name # 实例变量
        @@count += 1
    end
public # 默认public,可省略

def say_hi
    puts "Hi #{@name}!"
end
def say_bye
    puts "Bye #{@name}, come back soon."
end
def get_count
    return @@count
end

private

def bank_account_number
    @account_number = 12345
    puts "My bank account number is #{@account_number}."
end

end greeter = Greeter.new(“Pat”)

Object的内置方法

greeter.instance_of?(Greeter) # true greeter.instance_variables # [:@name] greeter.method(“say_hi”) # #<Method: Greeter#say_hi() eval:5> greeter.methods # show all greeter’s methods greeter.respond_to?(“say_hi”) # true; greeter.respond_to?(“name”) # false; tom = Greeter.new(“Tom”) tom.get_count # 2 greeter.get_count # 2

继承

class Cruise < Greeter
  def initialize(duration, price)
    super # 调用Greeter的initialize并继承超类的属性/方法
  end
end

attr_reader / attr_writer / attr_accessor方法 让实例可读取/写入变量

class Student
  attr_reader :name
  attr_writer :name
  # == attr_accessor :name # 可读可写
  def initialize(name)
    @name = name
  end
end
top_student = Student.new("Jyothi")
puts top_student.name # => Jyothi
top_student.name = "Anika"
puts top_student.name # => Anika

命名空间(namespace)

Math::PI

模块(module)

导入外部模块

require 'date'
puts Date.today  # 2023-02-23

创建模块

module Mod
  include Math # 使用include包含模块,就不需要Math::cos的写法了
  CONST = PI # from Math::PI
  def meth
    #  ...
  end
end
Mod.class              #=> Module
Mod.constants          #=> [:CONST, :PI, :E]
Mod.instance_methods   #=> [:meth]
Mod::CONST # => 3.14159.....
#### extend ####
class MyModClass
  extend Mod # 类扩展,可直接使用Mod下的方法,无需示例
end
MyModClass.meth

常用方法

var = "Codecademy"
var.length # 10
var.reverse # ymedacedoC
var.upcase # CODECADEMY
var.downcase # codecademy
var.next # Codecademz # y的下一个是z
var.next.next # Codecadena # z的下一个是a,m下一个是n
"Title".ljust(30) + 2023
# => "Title                         2023"
my_array = [3, 4, 8, 7, 1, 6, 5, 9, 2]
my_array.sort # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
print my_array # => [3, 4, 8, 7, 1, 6, 5, 9, 2]
my_array.sort!
print my_array # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
print my_array.to_s # => "[1, 2, 3, 4, 5, 6, 7, 8, 9]"
#### 查询对象的标识符 ####
my_array.object_id # => 480
1.object_id # => 3
a=1
a.object_id # => 3
#### 查询类型 ####
a.class # => Integer
#### 查询父类 ####
Integer.ancestors # [Integer, Numeric, Comparable, Object, Kernel, BasicObject]
#### hash合并 ####
hash1.merge!(hash2)

迭代器

#### .select / .each_key / .each_value ####
olympic_trials = {
  Sally: 9.58,
  John: 9.69,
  Bob: 14.91
}
olympic_trials.select { |name, time| time <  10.05 } # => {:Sally=>9.58, :John=>9.69}
olympic_trials.each_key { |key| print key }
#### .upto / .downto ####
"B".upto("F") { |letter| print letter, " " } # => B C D E F
5.downto(0) { |num| print num, " " } # => 5 4 3 2 1 0
#### .collect ####
first_arr = [3, 4, 5]
second_arr = first_arr.collect { |num| num * 5 }
print second_arr #Output => [15, 20, 25]

Ruby脚本文件范例

执行命令: ruby my_first_program.rb ```ruby

!/usr/bin/env ruby

class MegaGreeter attr_accessor :names

Create the object

def initialize(names = “World”) @names = names end

Say hi to everybody

def say_hi if @names.nil? puts “…” elsif @names.respond_to?(“each”)

@names is a list of some kind, iterate!

@names.each do |name| puts “Hello #{name}!” end else puts “Hello #{@names}!” end end

Say bye to everybody

def say_bye if @names.nil? puts “…” elsif @names.respond_to?(“join”)

Join the list elements with commas

puts “Goodbye #{@names.join(”, “)}. Come back soon!” else puts “Goodbye #{@names}. Come back soon!” end end end

if FILE == $0 =begin FILE contains the name of the current file $0 is the name of the file used to start the program This allows a file to be used as a library, and not to execute code in that context, but if the file is being used as an executable, then execute that code. =end mg = MegaGreeter.new mg.say_hi mg.say_bye

Change name to be “Zeke”

mg.names = “Zeke” mg.say_hi mg.say_bye

Change the name to an array of names

mg.names = [“Albert”, “Brenda”, “Charles”, “Dave”, “Engelbert”] mg.say_hi mg.say_bye

Change to nil

mg.names = nil mg.say_hi mg.say_bye end

=begin Output:

Hello World! Goodbye World. Come back soon! Hello Zeke! Goodbye Zeke. Come back soon! Hello Albert! Hello Brenda! Hello Charles! Hello Dave! Hello Engelbert! Goodbye Albert, Brenda, Charles, Dave, Engelbert. Come back soon! … … =end ```