# Debian, Ubuntu$ sudo apt-get install ruby-full# Windows$ winget install RubyInstallerTeam.Ruby $ brew install ruby # macOS$ docker run -it --rm ruby:latest # Docker$ docker run -it --rm ruby:2.7
使用包管理器安装 rbenv
$ brew install rbenv ruby-build # macOS# Debian、ubuntu 和其他衍生产品$ sudo apt install rbenv
使用 rbenv 安装 ruby
# 列出最新的稳定版本$ rbenv install -l# 列出所有本地版本$ rbenv install -L# 安装 Ruby 版本$ rbenv install 3.1.2$ rbenv global 3.1.2 # 为这台机器设置默认Ruby版本# 或者$ rbenv local 3.1.2 # 设置此目录的 Ruby 版本$ rbenv local --unset$ rbenv version # 显示当前活动的 Ruby 版本=> 1.9.3-p327 (set by /Users/sam/.rbenv/version)
使用 RVM 安装 ruby
$ curl -sSL https://get.rvm.io | bash -s stable$ rvm list # Ruby 版本列表$ rvm install 3.0.1 # 安装 3.0.1$ rvm use 3.0.1 # 使用 3.0.1
如何安装 ruby gem 管理器, bundler gem
# 访问 bash 以执行以下命令$ docker run -it --rm ruby:latest bash$ gem install bundler$ bundle -v$ gem update bundler$ gem uninstall bundler
Gemfile 是 Bundler(也是 gem)的配置文件,其中包含项目的 gem 列表(依赖项)
# 在项目根目录的 Gemfile 中指定 gemruby '2.5.6'source 'https://rubygems.org'gem 'nokogiri'gem 'rack', '~>1.1'gem 'rspec', :require => 'spec'
安装 Gemfile 中的所有 gem
$ bundle install
$ gem install bundler -v 1.17$ gem install minitest -v 5.8.4
# 使用 Bundler 更新单个 gem$ bundle update nokogiri# 使用 Bundler 更新 Gemfile 中的每个 gem$ bundle update
__ENCODING__ | 当前文件的脚本编码 |
__LINE__ | 当前文件中此关键字的行号 |
__FILE__ | 当前文件的路径 |
BEGIN | 包含在 { } 中的代码在程序运行之前运行 |
END | 包含在 { } 中以在程序结束时运行 |
alias | 为现有方法、运算符、全局变量创建别名 |
and | 逻辑与运算符 |
begin | 开始一段代码 |
break | 终止循环 |
case | 将表达式与匹配的 when 子句进行比较,其中 |
class | 定义一个类 |
def | 定义函数/方法 |
defined? | 检查某个变量、函数是否存在 |
do | 开始一个代码块并执行块中的代码,以 |
else | 如果先前的条件不成立,则执行以下代码 |
elsif | if 表达式的替代条件 |
end | 用于结束以 begin、class、def、do、if 等关键字开头的代码块 |
ensure | 总是在块终止时执行 |
false | 逻辑布尔假值 |
for | 开始一个 for 循环 |
if | 如果 if 的条件语句为 true,则执行代码块 |
in | 与 for 循环一起使用 |
module | 定义一个模块 |
next | 跳转到循环条件评估之前的点 |
nil | 为空或无效或始终为假 |
not | 逻辑否定运算符 |
or | 逻辑或运算符 |
redo | 条件循环后跳转 |
rescue | 在引发异常后评估表达式 |
retry | • 在救援之外调用时,重复方法调用 |
return | 从方法或代码块返回值 |
self | 当前对象 |
super | 调用超类中的同名方法 |
then | 与 if、unless、when、case、rescue 一起使用的分隔符 |
true | 逻辑布尔真 |
undef | 使当前类中的方法/函数未定义 |
until | 在条件语句为假时执行代码块 |
when | 在 case 语句下开始一个子句 |
while | 执行代码块,直到条件语句变为假 |
yield | 执行传递给方法的代码块 |
# 单行注释=begin多行注释=end=begin 注释第 1 行 =endputs "Hello world!" # 代码的内联注释
# 添加1 + 1 #=> 2# 减法2 - 1 #=> 1# 乘法2 * 2 #=> 4# 分配10 / 5 #=> 217 / 5 #=> 3, not 3.417 / 5.0 #=> 3.4# 指数2 ** 2 #=> 43 ** 4 #=> 81# 模数(求除法的余数)8 % 2 #=> 0 (8 / 2 = 4; 没有剩余)10 % 4 #=> 2 (10 / 4 = 2 余数为 2)a = 10b = 20a == b #=> falsea != b #=> truea > b #=> falsea < b #=> truea >= b #=> falsea <= b #=> true# 比较运算符a <=> b #=> -1c = 20c <=> b #=> 0c <=> a #=> 1# 用于测试 case 语句的 when 子句中的相等性(1...10) === 5 #=> true# 如果接收者和参数具有相同的类型和相等的值,则为真1.eql?(1.0) #=> falsec = a + b #=> 30c += a #=> 40c -= a #=> 30c *= a #=> 300c /= a #=> 30c %= a #=> 3c **= a #=> 59049# Ruby 并行赋值a = 10b = 20c = 30a, b, c = 10, 20, 30# Ruby 位运算符a = 60b = 13# & 如果两个操作数中都存在,则二进制 AND 运算符将位复制到结果中。a & b #=> 12# | 如果二进制或运算符存在于任一操作数中,则复制一个位。a | b #=> 61# ^ 二元异或操作符如果在一个操作数中设置,则复制该位,但不能同时在两个操作数中设置。a ^ b #=> 49# ~ 二进制补码运算符是一元的,具有“翻转”位的效果。~a# << 二进制左移运算符。 左操作数的值被移动# 左操作数指定的位数。a << 2# >> 二进制右移运算符。 左操作数的值被移动# 右操作数指定的位数。a >> 2# Ruby 逻辑运算符a and b #=> true.a or b #=> true.a && b #=> true.(a || b) #=> true.!(a && b) #=> false.not(a && b) #=> false.# Ruby 三元运算符# ? :# 如果条件为真? 然后值 X :否则值 Ya == 10 ? puts 'Right' : puts 'Wrong'# Ruby 范围运算符# .. 创建从起点到终点的范围(含)1..10 #=> 创建从 1 到 10 的范围(包括 1 到 10)# ... 创建一个从起点到终点的范围,不包括在内1...10 #=> 创建一个从 1 到 10 的独占范围
[a-z] 或 _ | 本地的 | count = 10 或 _count = 10 | 必须初始化局部变量 |
@ | 实例变量 | @id = [] | 实例变量在初始化之前具有“nil”值 |
@@ | 类变量 | @@name = [] | 必须初始化类变量 |
$ | 全局变量 | $version = "0.8.9" | 全局变量在初始化之前具有“nil”值 |
[A-Z] | 持续的 | PI = 3.14 | 常量变量必须初始化,您可以更改常量,但您会收到警告 |
有五种不同类型的变量。第一个字符确定范围
current_weather = "rainy"_weather = "sunny"
必须以下划线或小写字母开头
# 实例类变量@current_weather = "rainy"# 全局变量$current_weather = "rainy"# 常量变量WEATHER = "rainy".freeze
self | 当前方法的接收者对象 |
true | TrueClass 的实例 |
false | FalseClass 的实例 |
nil | NilClass 的实例 |
__FILE__ | 当前源文件名 |
__LINE__ | 当前源文件的当前行号 |
$-0 | $/ 的别名 |
$-a | 如果设置了选项 -a,则为真。只读变量 |
$-d | $DEBUG 的别名 |
$-F | $; 的别名 |
$-i | 在就地编辑模式下,此变量保存扩展,否则为零 |
$-I | $: 的别名 |
$-l | 如果选项 -lis 设置为真。只读变量 |
$-p | 如果选项 -pi 设置为真。只读变量 |
$-v | $VERBOSE 的别名 |
$! | 异常信息消息。raise 设置此变量 |
$@ | 最后一个异常的回溯,它是 String 的数组,指示调用方法的位置。格式中的元素如:“filename:line”或“filename:line:in `methodname'”(助记符:发生异常的地方) |
$& | 与此范围内最后一次成功的模式匹配匹配的字符串,如果最后一次模式匹配失败,则返回 nil。 (助记符:在某些编辑器中类似于 &)这个变量是只读的 |
$` | 当前范围内最后一次成功的模式匹配所匹配的任何内容之前的字符串,如果最后一次模式匹配失败,则为 nil。 (助记符:` 通常在带引号的字符串之前)此变量是只读的 |
$' | 当前范围内最后一次成功的模式匹配所匹配的字符串后面的字符串,如果最后一次模式匹配失败,则为 nil。 (助记符:' 通常跟在带引号的字符串之后) |
$+ | 最后一个成功的搜索模式匹配的最后一个括号,如果最后一个模式匹配失败,则为 nil。如果您不知道一组替代模式中的哪一个匹配,这很有用。 (助记:积极向上) |
, ... | 包含上一次成功匹配的模式中相应括号集中的子模式,不计算已经退出的嵌套块中匹配的模式,或者如果最后一次模式匹配失败,则为 nil。 (助记符:如 \digit)这些变量都是只读的 |
$~ | 当前范围内最后一个匹配的信息。设置此变量会影响匹配变量,如 $&、$+、、.. 等。第 n 个子表达式可以通过 $~[nth] 检索。 (助记符:~ 用于匹配)这个变量是局部作用域的 |
$= | 不区分大小写的标志,默认为 nil。 (助记符:= 用于比较) |
$/ | 输入记录分隔符,默认为换行符。像 awk 的 RS 变量一样工作。如果设置为 nil,则将立即读取整个文件。 (助记符:/ 用于在引用诗歌时划定行界) |
$\ | print 和 IO#write 的输出记录分隔符。默认值为无。 (助记符:它就像 /,但它是你从 Ruby 中“返回”的东西) |
$, | 打印的输出字段分隔符。此外,它是 Array#join 的默认分隔符。 (助记符:当您的打印语句中有 , 时打印的内容) |
$; | String#split 的默认分隔符。 |
$. | 读取的最后一个文件的当前输入行号。 |
$< | 由命令行参数或标准输入给出的文件的虚拟连接文件(如果没有提供参数文件)。 $<.file 返回当前文件名。 (助记符:$< 是一个 shell 输入源) |
$> | print 的默认输出,printf。 $stdout 默认情况下。 (助记符:$> 用于 shell 输出) |
$_ | 通过gets或readline输入String的最后一行。如果gets/readline 遇到EOF,它被设置为nil。这个变量是局部作用域的。 (助记符:部分与 Perl 相同) |
$0 | 包含包含正在执行的 Ruby 脚本的文件的名称。在某些操作系统上,分配给 包含包含正在执行的 Ruby 脚本的文件的名称。在某些操作系统上,分配给 $0 会修改 ps(1) 程序看到的参数区域。作为一种指示当前程序状态的方式,这比隐藏您正在运行的程序更有用。 (助记符:与 sh 和 ksh 相同) 会修改 ps(1) 程序看到的参数区域。作为一种指示当前程序状态的方式,这比隐藏您正在运行的程序更有用。 (助记符:与 sh 和 ksh 相同) |
$* | 为脚本提供的命令行参数。 Ruby 解释器的选项已被删除。 (助记符:与 sh 和 ksh 相同) |
$$ | 运行此脚本的 Ruby 的进程号。(助记符:与贝壳相同) |
$? | 最后执行的子进程的状态。 |
$: | 该数组包含通过 load 或 require 查找 Ruby 脚本和二进制模块的位置列表。 它最初由任何 -I 命令行开关的参数组成,然后是默认的 Ruby 库,probabl "/usr/local/lib/ruby",然后是 ".",表示当前目录 . (助记符:冒号是 PATH 环境变量的分隔符) |
$" | 该数组包含由 require 加载的模块名称。 用于防止 require 两次加载模块。助记符:防止文件被双引号(加载) |
$DEBUG | -d 开关的状态。 |
$FILENAME | 与$<.filename 相同 |
$LOAD_PATH | $: 的别名 |
$stdin | 当前的标准输入 |
$stdout | 当前的标准输出 |
$stderr | 当前标准错误输出 |
$VERBOSE | 详细标志,由 -v 开关设置到 Ruby 解释器 |
TRUE | 典型的真值。在 Ruby 中,所有非 false 值(除了 nil 和 false 之外的所有值)都是 true |
FALSE | 虚假本身 |
NIL | 零本身 |
STDIN | 标准输入。$stdin 默认值 |
STDOUT | 标准输出。$stdout 默认值 |
STDERR | 标准错误输出。$stderr 默认值 |
ENV | 类哈希对象包含当前环境变量。 在 ENV 中设置值会更改子进程的环境 |
ARGF | $< 的别名 |
ARGV | $* 的别名 |
DATA | 脚本的文件对象,就在 END 之后。 除非未从文件中读取脚本,否则未定义 |
VERSION | Ruby 版本字符串 |
RUBY_RELEASE_DATE | 发布日期字符串 |
RUBY_PLATFORM | 平台标识符 |
defined? count"local-variable"defined? @id"instance-variable"defined? @@name"class variable"defined? $version"global-variable"defined? PI"constant"
类型 | 示例 | Class | 文档 |
Integer | a = 17 | a.class > Integer | # |
Float | a = 87.23 | a.class > Float | # |
String | a = "Hello universe" | a.class > String | # |
Array | a = [12, 34] | a.class > Array | # |
Hash | a = {type: "tea", count: 10} | a.class > Hash | # |
Boolean | a = false | a.class > FalseClass | TrueClass FalseClass |
Symbol | a = :status | a.class > Symbol | # |
Range | a = 1..3 | a.class > Range | # |
Nil | a = nil | a.class > NilClass | # |
进一步阅读
# 两者都是同义词a = 37a.kind_of? Integer# truea.is_a? Integer# true
week_days = {sunday: 11, monday: 222}
2.even?# true3.even?# false
.. 用于创建包含范围
range = 1..10range.to_a# 输出 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
... 用于创建专属范围
range = 1...10range.to_a# 输出 => [1, 2, 3, 4, 5, 6, 7, 8, 9]
一些有用的方法
cover? | (1..5).cover?(5) => true |
end | ('a'..'z').end => "z" |
first | (1..5).first => 1 |
first(3) | ('A'..'Z').first(2) => ["A", "B"] |
eql? | ((0..2).eql?(0..5) => false |
(1..20).step(2) { |number| puts "#{number}"}# 输出# 1# 3# 5# 7# 9# 11# 13# 15# 17# 19
num = 2puts 'two' if num == 2
如果条件为真,则执行代码
temp = 19if temp >= 25 puts "hot"elsif temp < 25 && temp >= 18 puts "normal"else puts "cold"end# 输出 => normal
# 除非与 if 相反,当语句为假时进行评估name = "rob"# if name != "bob"unless name == "bob" puts "hello stranger"else puts "hello bob"end# 输出 => hello strangernum = 6puts 'not two' unless num == 2# 输出 => not two
# case 返回最后执行的表达式的值case input# 检查一个整数,19when 19 puts "It's 19" # 检查浮点数,33.3when 33.3 puts "It's 33.3" # 检查一个确切的字符串,“Zaman”when "Zaman" puts "Hi Zaman"when 10 puts "It's 10" # 检查范围when 7..11 puts "It's between 7 and 11" # 检查多个值,“咖啡”when "tea", "coffee" puts "Happy days" # 检查正则表达式“aA6”when /^a[A-Z]+[0-6]+$/ puts "It's a valid match" # 通过与 String 类“任何字符串” # 进行比较来检查任何字符串when String puts "It's a String"end
case input when 19 then puts "It's 19"end
case input when 19 then puts "It's 19"else puts "It's not 19"end
marks = 86result = case marks when 0..49 then "Fail" when 50..64 then "Pass" when 65..74 then "Credit" when 75..84 then "Distinction" when 85..100 then "High Distinction" else "Invalid marks" endputs result# High Distinction
name = "World"puts "Hello #{name}"puts "The total is #{1+1}"# "the total is 2"
字符串插值允许您将字符串组合在一起
string = "abc123"string[0,3]# "abc"string[3,3]# "123"string[0..-2]# "abc12"#remove or replace the substringstring[0..2] = ""puts string# "123"
子字符串是字符串的一小部分,如果你只想要那个特定的部分,它会很有用,比如开头、中间或结尾
"HELLO World".downcase # "hello world""hello worlD".upcase # "HELLO WORLD""hEllo wOrlD".capitalize # "Hello world""hEllo WOrlD".swapcase # "HeLLO woRLd"
length or size | "HELLO World".length => 11 | 返回字符串的长度 |
reverse | "hello worlD".reverse => "Dlrow olleh" | 返回反转的字符串 |
include? other_str | "hEllo wOrlD".include? "w" => true | 如果字符串或字符存在则返回 true,否则返回 false |
gsub(pattern, replacement) | "hEllo wOrlD".gsub(" ", "_") => "hEllo_wOrlD" | gsub 或全局替换用提供的字符串替换一个或多个字符串 |
gsub(pattern, hash) | "organization".gsub("z", 'z' => 's') => "organisation" | gsub 或全局替换用提供的哈希替换一个或多个字符串 |
gsub(pattern) { |match| block} | "Price of the phone is 1000 AUD".gsub(/\d+/) { |s| '$'+s } | gsub 或全局替换用提供的块替换一个或多个字符串 |
strip | " hEllo WOrlD ".strip | 它将删除(修剪)以下任何前导和尾随字符:null(“\x00”)、水平制表符(“\t”)、换行符(\n)、垂直制表符(“\v”)、换页符(f)、回车(\r)、空格(" ") |
prepend | a = "world" <br> a.prepend("hello ") | 在另一个字符串之前添加字符串 |
insert | a = "hello" <br> a.insert(a.length, " world") | 在特定位置插入字符串 |
start_with? | string = "ruby programming" | 检查字符串是否以特定前缀开头 |
end_with? | string = "ruby programming" | 检查字符串是否以特定前缀结尾 |
delete_suffix | string = "sausage is expensive" | 从字符串中删除后缀 |
delete_prefix | string = "sausage is expensive" | 从字符串中删除前缀 |
split | string = "a b c d" <br> string.split | 将字符串转换为字符数组 |
join | arr = ['a', 'b', 'c'] <br> arr.join => "abc" | 将数组转换为字符串 |
to_i | a = "49" <br> a.to_i => 49 | 将字符串转换为整数 |
chop | "abcd?".chop("?") => "abcd" | 从字符串中删除最后一个字符 |
count | str = "aaab" <br> str.count("a") | 计算字符串中的字符 |
to_f | a = "49" | 将字符串转换为浮点数 |
to_sym | a = "key" | 将字符串转换为符号 |
match | "abcd?".match(/ab/) => #<MatchData "ab"> | 将模式转换为正则表达式并在字符串上调用其匹配方法 |
empty? | "hello".empty? => false | 如果字符串的长度为零,则返回 true |
squeeze | "Booook".squeeze => "Bok" | 返回字符串的副本,其中相同字符的运行被单个字符替换 |
* | puts "Ruby " * 4 => Ruby Ruby Ruby Ruby | 返回多个 self 副本的串联 |
+ | "sammy " + "shark" => "sammyshark" | 返回 self 和给定的其他字符串的连接 |
eql? | s = 'foo' => true | 如果对象具有相同的长度和内容,则返回 true;作为自己;否则为假 |
+ | "sammy " + "shark" => "sammyshark" | 返回 self 和给定的其他字符串的连接 |
+ | "sammy " + "shark" => "sammyshark" | 返回 self 和给定的其他字符串的连接 |
def method_name(parameter1, parameter2) puts "#{parameter1} #{parameter2}" parameter1 + parameter2end
res = method_name(20, 10)# 输出 => 30def method_name(parameter1, parameter2) puts "#{parameter1} #{parameter2}" return parameter1 + parameter2end# 输出 => 30
res = method_name(parameter1, parameter2)# 可以调用不带括号的方法res = method_name parameter1, parameter2
类方法是类级别的方法。 有多种定义类方法的方法
class Mobile def self.ring "ring ring ring..." endendMobile.ring
class Mobile def Mobile.ring "ring ring ring..." endendMobile.ring
class Mobile class << self def ring "ring ring ring..." end endendMobile.ring
类方法是类对象的实例方法。 当创建一个新类时,“Class”类型的对象被初始化并分配给一个全局常量(在本例中为 Mobile)
Mobile = Class.new do def self.ring "ring ring ring..." endendMobile.ring
Mobile = Class.newclass << Mobile def ring "ring ring ring..." endendMobile.ring
def method_name(num1, num2 = num1) return num1 + num2endres = method_name(10)# 输出 => 20
def method_name(parameter1, parameter2, type = "ADD") puts "#{parameter1} #{parameter2}" return parameter1 + parameter2 if type == "ADD" return parameter1 - parameter2 if type == "SUB"endres = method_name(20, 10)# 输出 => 30
def method_name(type, *values) return values.reduce(:+) if type == "ADD" return values.reduce(:-) if type == "SUB"endnumbers = [2, 2, 2, 3, 3, 3]res = method_name("ADD", *numbers)# 输出 => 15res = method_name("SUB", *numbers)# 输出 => -11# 或者您可以提供这样的值res = method_name("ADD", 2, 2, 2, 3, 3, 3)# 输出 => 15
a = ["Drama", "Mystery", "Crime","Sci-fi", "Disaster", "Thriller"]a.sortputs a# 我们没有修改对象# Drama# Mystery# Crime# Sci-fi# Disaster# Thrillera.sort!puts a# 修改对象# Crime# Disaster# Drama# Mystery# Sci-fi# Thriller
当您要修改对象时,在方法之后使用 !
在 ruby 中,以问号 (?) 结尾的方法称为布尔方法,它返回 true 或 false
"some text".nil?# falsenil.nil?# true
您可以拥有自己的布尔方法
def is_vowel?(char) ['a','e','i','o','u'].include? charendis_vowel? 'a'# trueis_vowel? 'b'# false
# return valuedef give_me_data data = yield puts "data = #{data}"endgive_me_data { "Big data" }# 输出 => data = Big data
do 和 end(用于多行)或花括号 { 和 }(用于单行)之间的代码称为块,它们可以在两个管道之间定义多个参数 (|arg1, arg2|)
salary = [399, 234, 566, 533, 233]salary.each { |s| puts s }# puts s = block body# |s| = block arugments
salary.each do |s| a = 10 res = a * s puts resend# 块体# a = 10# res = a * s# puts res# 块参数# |s|
块可以作为方法参数传递,也可以与方法调用相关联。 块返回最后评估的语句
def give_me_data puts "I am inside give_me_data method" yield puts "I am back in give_me_data method"endgive_me_data { puts "Big data" }# 输出# I am inside give_me_data method# Big data# I am back in give_me_data method
def give_me_data yield yield yieldendgive_me_data { puts "Big data" }# 输出# Big data# Big data# Big data
def give_me_data yield 10 yield 100 yield 30endgive_me_data { |data| puts "Big data #{data} TB" }# 输出# Big data 10 TB# Big data 100 TB# Big data 30 TB
def give_me_data yield "Big data", 10, "TB" yield "Big data", 100, "GB" yield "Big data", 30, "MB"endgive_me_data { |text, data, unit| puts "#{text} #{data} #{unit}" }# 输出# Big data 10 TB# Big data 100 GB# Big data 30 MB
give_me_data puts "我在 give_me_data 方法里面"enddef test puts "我在测试方法里面" give_me_data { return 10 } # 代码从这里返回 puts "I am back in test method"endreturn_value = test# 输出# 我在测试方法里面# 我在 give_me_data 方法里面# 10
def give_me_data(&block) block.call block.callendgive_me_data { puts "Big data" }# 输出# Big data# Big data
def give_me_data yieldendgive_me_data# 输出# LocalJumpError: no block given (yield)
def give_me_data return "no block" unless block_given? yieldendgive_me_data { puts "Big data" }give_me_data# 输出# Big data
p = Proc.new { puts "Hello World" }def give_me_data(proc) proc.callendgive_me_data p# 输出# Hello World
proc 就像一个可以存储在变量中的块
p = Proc.new { |count| "Hello World " * count }def give_me_data(proc) proc.call 5, 2endgive_me_data p# 输出# "Hello World Hello World Hello World Hello World Hello World "
p = Proc.new { return 10 }p.call# 输出LocalJumpError: unexpected return
def give_me_data puts "我在 give_me_data 方法里面" p = Proc.new { return 10 } p.call # 代码从这里返回 puts "I am back in give_me_data method"endreturn_value = give_me_dataputs return_value# 输出# 我在 give_me_data 方法里面# 10
l = lambda { puts "Hello World" }# 速记l = -> { puts "Hello World" }# 调用 lambdal.call# 输出 => Hello World
有多种方法可以调用 lambda
l.()l[]
l = -> (count) { "Hello World " * count }l.call 5# 输出# "Hello World Hello World Hello World Hello World Hello World "l.call 5, 2# 输出wrong number of arguments (given 2, expected 1)
def give_me_data puts "I am inside give_me_data method" l = -> { return 10 } l.call puts "I am back in give_me_data method"endreturn_value = give_me_dataputs return_value# 输出# I am inside give_me_data method# I am back in give_me_data method# nil # because puts return nil
l = -> { return 10 }l.call# 输出 => 10
array = Array.new #=> []# orarray = []
array = [1, "two", 3.0] #=> [1, "two", 3.0]
numbers = Array.new(3) #=> [nil, nil, nil]numbers = Array.new(3, 7) #=> [7, 7, 7]numbers = Array.new(3, true) #=> [true, true, true]numbers = []numbers.fill(7, 0..2) #=> [7, 7, 7]
array_with_hashes = Array.new(2) { {} } #=> [{}, {}]array_with_hashes[0][:name] = "Bob"array_with_hashes[0][:id] = 10 #=> [{:name=>"Bob", :id=>10}, {}]
temperature_data = [ ["A908", 38], ["A909", 37], ["A910", 38], ]temperature_data[0] #=> ["A908", 38]temperature_data[0][0] #=> "A908"temperature_data[0][1] #=> 38
str_array = [ "This", "is", "a", "small", "array"]str_array[0] #=> "This"str_array[1] #=> "is"str_array[4] #=> "array"
str_array = [ "This", "is", "a", "small", "array"]# 索引 -1 表示最后一个元素str_array[-1] #=> "array"# 索引 -2 表示倒数第二个元素str_array[-2] #=> "small"str_array[-6] #=> nil
str_array = [ "This", "is", "a", "small", "array"]puts str_array.at(0) #=> "This"
arr = [1, 2, 3, 4, 5, 6]arr[100] #=> nilarr[-3] #=> 4arr[2, 3] #=> [3, 4, 5]arr[1..4] #=> [2, 3, 4, 5]arr[1..-3] #=> [2, 3, 4]
arr = ['a', 'b', 'c', 'd', 'e', 'f']arr.fetch(100)#=> IndexError: 数组边界外的索引 100:-6...6arr.fetch(100, "oops") #=> "oops"
超出边界,给默认值
arr = [1, 2, 3, 4, 5, 6]arr.first # 第一个值 => 1arr.last # 最后一个值 => 6# take 返回前 n 个元素arr.take(3) #=> [1, 2, 3]# drop 在 n 个元素被删除之后arr.drop(3) #=> [4, 5, 6]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.push(11) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]numbers.push(12, 13, 14) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
num_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]num_array.pop #=> 10num_array#=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.unshift(-3, -2, -1) #=> [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.shift #=> 1numbers#=> [2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.delete_at(2) #=> 4numbers #=> [2, 3, 5, 6, 7, 8, 9, 10]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.delete(2) #=> 2numbers #=> [3, 5, 6, 7, 8, 9, 10]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.insert(0, 0) #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.insert(0, -3, -2, -1) #=> [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.insert(-1, 12, 13, 14) #=> [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14]numbers.insert(-4, 11) #=> [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
numbers = Array.new(10) { |n| n = n * 2 } #=> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
numbers = Array(100..110)#=> [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110]# 或者我们可以将范围转换为数组(100..110).to_a #=> [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110]
arr = ['foo', 0, nil, 'bar', 7, nil]arr.compact #=> ['foo', 0, 'bar', 7]arr #=> ['foo', 0, nil, 'bar', 7, nil]arr.compact! #=> ['foo', 0, 'bar', 7]arr #=> ['foo', 0, 'bar', 7]
arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]planets.include? "Mars"# 输出 => trueplanets.include? "Pluto"# 输出 => false
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]planets.size# 输出 => 8planets.length# 输出 => 8
您可以使用大小或长度,两者都是同义词
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.clear# 输出 => []
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers[0]# ornumbers.first# 输出 => 1
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers[-1]# ornumbers.last# 输出 => 10
a = ["tom", "mot", "otm"]b = [2, 3, 5]a.zip(b)# 输出# [["tom", 2], ["mot", 3], ["otm", 5]]
primes = [7, 2, 3, 5]sorted_primes = primes.sortputs "#{sorted_primes}"# 输出 => [2, 3, 5, 7]
or in-place sort
primes = [7, 2, 3, 5]primes.sort!puts "#{primes}"# 输出 => [2, 3, 5, 7]
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]planets.sort# 输出# ["Earth", "Jupiter", "Mars", "Mercury", "Neptune", "Saturn", "Uranus", "Venus"]planets.sort_by { |p| p }# 输出# ["Earth", "Jupiter", "Mars", "Mercury", "Neptune", "Saturn", "Uranus", "Venus"]planets.sort_by { |p| p.length }# 输出# ["Mars", "Earth", "Venus", "Saturn", "Uranus", "Neptune", "Jupiter", "Mercury"]
primes = [7, 2, 3, 5]primes.max_by { |p| p }# 输出 => 7
# numbers[start..end], both index are inclusiveputs numbers[0..3]# 1# 2# 3# 4# numbers[start..end], end index is exclusiveputs numbers[0...3]# 1# 2# 3# or numbers[start..length]puts numbers[0, 1]# 1
primes = [7, 2, 3, 5]primes.take(3)# [7, 2, 3]
primes = [7, 2, 3, 5]primes.fetch(3)# 5# Fetch will throw an error if the element does not existprimes.fetch(10)# (index 10 outside of array bounds: -4...4)# or get an default valueprimes.fetch(10, -1)# -1
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 1]numbers.uniq# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
primes = [7, 2, 3, 5]primes.drop(3)# [5]
primes = [7, 2, 3, 5]primes.shift# [2, 3, 5]
primes = [7, 2, 3, 5]primes.pop# [7, 2, 3]
primes = [7, 2, 3, 5]primes.delete_at(-1)# [7, 2, 3]
primes = [7, 2, 3, 5, 5]primes.delete(5)# [7, 2, 3]
# 当你有单行块时salary = [399, 234, 566, 533, 233]salary.each { |s| puts s }# 输出# 399# 234# 566# 533# 233
当你有一个多行块时,你可以用 do 和 end 替换花括号 {}
salary.each do |s| a = 10 res = a * s puts resend# 输出# 3990# 2340# 5660# 5330# 2330
或者您可以使用大括号 {} 和分号作为分隔符而不是换行符来做同样的事情
salary.each { |s| a = 10 ; res = a * s ; puts res }
salary = [399, 234, 566, 533, 233]salary.each_with_index { |value, index| puts "#{index} #{value}" }# 输出# 0 399# 1 234# 2 566# 3 533# 4 233
salary = [399, 234, 566, 533, 233]salary.each_index { |i| puts i}# 输出# 0# 1# 2# 3# 4
salary = [399, 234, 566, 533, 233]salary.map { |s| s * 10 }# 返回# [3990, 2340, 5660, 5330, 2330]# 另一方面,每个都返回原始值salary = [399, 234, 566, 533, 233]salary.each { |s| s * 10 }# 返回# [399, 234, 566, 533, 233]
salary = [399, 234, 566, 533, 233]salary.collect { |s| s > 400 }# 输出# [false, false, true, true, false]
for value in [2, 3, 5, 7] puts valueend
colors = [ {color: "red", count: 3}, {color: "red", count: 5}, {color: "black", count: 4}]colors.each_with_object(Hash.new(0)) { |color, hash| hash["color_"+color[:color]] = color[:color].upcase; hash["count_"+color[:color]] += color[:count] }# 输出{"color_red"=>"RED", "count_red"=>8, "color_black"=>"BLACK", "count_black"=>4}[1, 2, 3].each_with_object(0) { |number, sum| sum += number}# 输出# 0# 因为0是不可变的,由于初始对象是0,所以方法返回0
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]index = 0while index < planets.size puts "#{planets[index]}" index += 1end
a = 1star = '*'while a <= 10 puts star star += '*' a += 1end
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]index = 0loop do puts "#{planets[index]}" index += 1 break if planets[index] == "Mars" or index > planets.sizeend
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]index = planets.size - 1until index < 0 puts "#{planets[index]}" index -= 1end
a = 1star = '*'until star.length > 10 puts star star += '*' a += 1end
10.times { puts "#{rand(1..100)}"}# 输出# 将打印 10 个随机数
仅仅因为你可以并不意味着你应该像这样迭代一个数组
data_sample = [2, 3, 5, 7]data_sample.size.times { |index| puts "#{data_sample[index]}" }# 输出# 2# 3# 5# 7
data_sample = [2, 3, 5, 7]0.upto((data_sample.size - 1) / 2) { |index| puts "#{data_sample[index]}" }# 输出# 2# 3
data_sample = [2, 3, 5, 7](data_sample.size - 1).downto(data_sample.size / 2) { |index| puts "#{data_sample[index]}" }# 输出# 7# 5
1.step(20, 2) { |number| puts "#{number}"}# 输出# 1# 3# 5# 7# 9# 11# 13# 15# 17# 19
19.step(1, -2) { |number| puts "#{number}"}# 输出# 19# 17# 15# 13# 11# 9# 7# 5# 3# 1
numbers = [2, 2, 2, 2, 2]numbers.inject{ |res, n| res + n }# 输出是所有数字之和的结果# 如果不给res设置初始值,则数组的第一个元素作为res的初始值# 10# 现在将 res 的值设置为 11numbers = [2, 2, 2, 2, 2]numbers.inject(11) { |res, n| res + n }# so 11 + 2, 13 + 2, 15 + 2, 17 + 2 and 19 + 2# 21# using symbolnumbers = [2, 2, 2, 2, 2]numbers.inject(:+)# 输出# 10
使用初始值和符号
numbers = [2, 2, 2, 2, 2]numbers.inject(11, :+)# 输出# 21
numbers = [2, 2, 2, 2, 2]numbers.reduce(11, :+)# 输出# 21
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]planets.detect { |name| name.start_with?("E") and name.end_with?("h") }# output# Earthsalary = [399, 234, 566, 533, 233]salary.detect { |s| s > 1000 }# output# nil
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]planets.find { |name| name.start_with?("E") and name.end_with?("h") }# output# Earth
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.select { |n| n % 2 == 0 }# 现在你有一个偶数数组# [2, 4, 6, 8, 10]# 如果没有满足您的逻辑的值,则返回一个空数组[1, 1, 1].select { |n| n % 2 == 0 }# no even numbers# []
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.reject { |n| n % 2 == 0 }# 如果数字是偶数则拒绝,所以现在我们有一个奇数数组# [1, 3, 5, 7, 9]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.keep_if { |n| n % 2 == 0 }# numbers 数组仅包含偶数# [2, 4, 6, 8, 10]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]numbers.delete_if { |n| n % 2 == 0 }# numbers 数组仅包含奇数# [1, 3, 5, 7, 9]
numbers = [1, 2, 3, 1, 2, 3, 0]numbers.drop_while { |n| n < 3 }# 是 3 小于 3,返回 false,所以删除 1, 2# [3, 1, 2, 3, 0]
words = %w[first second third fourth fifth sixth]str = ""words.reverse_each {|word| str += "#{word} "}p str #=> "sixth fifth fourth third second first "
all? | 当您想检查所有元素是否满足您的条件时 |
any? | 当您想检查至少一项是否满足您的条件时 |
one? | 当您想检查一个元素是否满足您的要求时 |
none? | 当您想检查是否没有任何项目满足您的条件时,相反? |
empty? | 当你想检查对象是否为空时 |
include? | 当你想检查元素是否存在于对象中时 |
[2, 4, 6, 8, 10].all? { |num| num % 2 == 0 }# true[1, 4, 6, 8, 10].all? { |num| num % 2 == 0 }# false
[1, 3, 5, 7, 10].any? { |num| num % 2 == 0 }# true[1, 3, 5, 7, 19].any? { |num| num % 2 == 0 }# false
[1, 3, 2, 5, 7].one? { |num| num % 2 == 0 }# true[1, 3, 2, 5, 4].one? { |num| num % 2 == 0 }# false
[1, 3, 5, 7, 9].none? { |num| num % 2 == 0 }# true[2, 3, 5, 7, 9].none? { |num| num % 2 == 0 }# false
[].empty?# true[1, 3, 5, 7, 9].empty?# false
[0, 1, 2, 3] & [1, 2] # => [1, 2][0, 1, 0, 1] & [0, 1] # => [0, 1]
[0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3])# => [0, 1][0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3])# => [0, 1]
a = [0, 1] + [2, 3]a # => [0, 1, 2, 3]
[0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3][0, 1, 2, 3] - [3, 0] # => [1, 2][0, 1, 2] - [4] # => [0, 1, 2]
[0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7][0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3][0, 1, 2, 3].union([3, 2], [1, 0]) # => [0, 1, 2, 3]
[0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1])# => [0, 2, 3][0, 1, 2, 3].difference([3, 0], [1, 3])# => [2][0, 1, 2].difference([4])# => [0, 1, 2]
a = [0, 1, 2]a1 = [3, 4]p = a.product(a1)p.size # => 6 # a.size * a1.sizep # => [[0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4]]
# variable countcount = 4# using while loop# here conditional is count i.e. 4while count >= 1 # statements to be executed puts "Ruby Cheatsheet" count = count - 1 # while loop ends hereend
输出
Ruby CheatsheetRuby CheatsheetRuby CheatsheetRuby Cheatsheet
# loop using range as expressiontext = "Ruby Cheatsheet"# using for loop with the rangefor count in 1..5 do puts textend
输出
Ruby CheatsheetRuby CheatsheetRuby CheatsheetRuby CheatsheetRuby Cheatsheet
# starting of do..while looploop do puts "Ruby Cheatsheet" val = '7' # using boolean expressions if val == '7' break end # ending of ruby do..while loopend
输出
Ruby Cheatsheet
var = 7# here do is optionaluntil var == 11 do # code to be executed puts var * 10 var = var + 1 # here loop endsend
输出
708090100
salary = [399, 234, 566, 533, 233]salary.each do |s| break if s == 566 puts send# 输出# 399# 234
通过使用 break 关键字
salary = [399, 234, 566, 533, 233]salary.each do |s| next if s == 533 puts send# 输出# 399# 234# 566# 233
通过使用 next 关键字
data = [456, 3000]retry_count = 0status = "network failure"sum = 0data.each do |d| if retry_count == 3 status = "connection established" retry_count = 0 redo elsif status == "network failure" and retry_count < 5 puts "network failure #{retry_count}" retry_count += 1 redo elsif status == "connection established" puts d sum += d endend# output of sum# 3456
numbers = [2, 2, 44, 44]sum = 0begin numbers.each do |s| if rand(1..10) == 5 puts "hi 5, let's do it again!" sum = 0 raise "hi 5" end puts s sum += s endrescue retryend
class Person # when you create a new object, it looks for a method named initialize and executes it, like a constructor in java # def initialize(name, number) # @name = name # @number = number # end # instance variable # @name # class variable # @@count # attr_accessor acts as a getter and setter for the following instance attributes attr_accessor :name, :number # class variable must be initialized @@count = 0 def self.count @@count end def self.count=(count) @@count = count end def initialize @@count += 1 endend# create an instance of the Person classp1 = Person.new# set attributes of the Person classp1.name = "Yukihiro Matsumoto"p1.number = 9999999999# get attributes of the Person classputs "#{p1.name}"puts "#{p1.number}"puts "#{Person.count}"# Yukihiro Matsumoto# 9999999999# 1p2 = Person.newp2.name = "Yukihiro Matsumoto"p2.number = 9999999999# get attributes of the Person classputs "#{p2.name}"puts "#{p2.number}"puts "#{Person.count}"# Yukihiro Matsumoto# 9999999999# 2# set class variablePerson.count = 3puts "#{Person.count}"# 3
class Person attr_accessor :name, :numberend# 使用 < 符号从父类继承方法和属性class Student < Person attr_accessor :idends = Student.news.name = "James Bond"s.number = 700s.id = 678puts "#{p.name}"James Bondputs "#{p.number}"700puts "#{p.id}"678
class Vehicle; endclass Car < Vehicle; endclass Audi < Car; endcar = Car.newcar.instance_of? Vehiclefalsecar.instance_of? Cartruecar.instance_of? Audifalsea = 7a.instance_of? Integertruea.instance_of? Numericfalse
如果对象是给定类的实例,而不是子类或超类,则返回 true
puts (String.methods).sort# 排除从 Object 类继承的方法puts (String.methods - Object.public_instance_methods).sort
String.respond_to?(:prepend)trueString.respond_to?(:append)false
官网 ruby-lang.org