Ruby 趣学笔记(一)

本文写于 2020 年 5 月 6 日

最近在 mac 上探索到了 homebrew 的使用方法,对 ruby 的兴趣直线上升,所以来学一学。

最近几年确实大家一直在唱衰 Ruby,整个社区的生态确实也不如 python 那么庞大,但是这都不妨碍 ruby 被称作“快乐编程”。

这几年越来越强调语言的性能,但是 Ruby 的作者松本行弘却认为,人才是最重要的!

自看到这句话的第一眼,我就深以为同!

其实这就是一个价值观的问题:人更值钱,那么就应该尽量节省人力;机器算力更值钱,那么就应该用人力去优化程序,来节省机器的算力。但是国内的大环境大家也懂,人多爆了......

自然而然,从上面的结论来看,Ruby 在国内不会流行。

作为多范式编程语言,Ruby 会比 Java 等更难协作;作为解释型语言,运行速度肯定比不上 C++ 超级慢……可很多人对于 Ruby 的评价仍然是:程序员的一把尖刀!

并且在 web 开发领域,还有一些大公司(GitHub)坚持在使用 Ruby,这足以说明 Ruby 的强大了!

变量

变量声明

Ruby 的变量声明不需要关键字,也不需要类型信息。

message = 'hello world'
_num = 0 $h = [1, 2, 3]

小写开头、_ 开头的变量是局部变量;$ 开头的单词是全局变量。

并且默认 Ruby 不存在闭包。

在函数内访问上级作用域的局部变量会报错。

变量类型

Ruby 不存在所谓的“基本类型”,比如 int / float / char...Ruby 只存在一个类型:对象。

一切皆对象的原则被严格恪守!我们可以不严谨的认为:Ruby 的类型就是对象。

什么意思呢?

print(1.to_s)

to_s 天生的就是 1 的方法!数字 1 其实就是 Number 对象的实例。

Ruby 的数据类型有 Number、String、Ranges、Symbols,以及 true、false 和 nil,以及 Array、Hash。

其中比较有意思的是 true 和 false,他们的 class 并不是 Boolean,而是 TrueClassFalseClass

甚至连 class 都有 class——Class

事实上,所有变量的 class 的 class,都是 Class 类。

常量

如同变量一样,Ruby 的常量声明也是通过约定。

所有首字母大写就代表常量,通常我们习惯将常量全大写(也有例如 GOLANG 以及一些其他语言推荐使用大驼峰命名)。

MAX_COUNT = 100

但 Ruby 毕竟还是个动态语言,即使是常量,我们也是可以强行修改的,只是会警告你而已。

MAX_COUNT = 100
MAX_COUNT = 101 p MAX_COUNT # 101

输出

Ruby 存在三种输出语句 print puts p

其中,p 语句的输出可以让我们看到更多的信息,例如

p "hello" # "hello"
puts "hello" # hello

p 可以让我们看到是否是字符串,puts 则不可以。

所以一般程序中输出时会用 p,日志输出用 printputs

字符串

Ruby 可以用单引号或者双引号标注字符串,单引号中不会自动将转义字符转义、双引号会自动转义。

p "a\nb" # 会换行
p 'a\nb' # 不会换行,直接输出 \n

双引号中还可以进行类似 JS 的模板字符串的插值:"hello #{userName}"

Ruby 也支持多行字符串。

str = <<fuck
1
2
3
3
fuck

<< 后跟上某一个字符串,直到遇见相同的字符串,多行字符串就会结束。

str = <<fuck
1
2
3
3fuck

但这种情况不会结束,所以结束符必须位于单行。

字符串操作

  • +:字符连接
  • <<:字符带入
  • *:字符循环
a = "hello";
b = "world";
puts a + " " + b; # <<:字符带入
a << b
puts a
puts b # 这个其实相当于 a = a + b # *:字符循环
a = "A"
puts a * 4

Array

games = ['魔兽世界', '塞尔达传说', '金庸群侠传']
puts games

这个 games 的定义,如果你在 RubyMine 或者其他强大的 IDE 中编写,他就会告诉你,有更好的方式:games = %w[魔兽世界 塞尔达传说 金庸群侠传]

这就是为什么 Ruby 不易协作,一千个程序员有一千种写法与实现方法!

数组的遍历

这是永远的重点,编程中最为常用的方法。

Ruby 可以通过 each 来遍历数组,具体语法如下:

games.each do |game|
puts "我喜欢#{game}"
end

这个地方稍微提一句,我曾在某个地方看到过,写单引号的程序最后会比写双引号的小(文件大小)。但是这里这种模板字符串的写法,必须要双引号。

带上数组下标的遍历

games.each_with_index do |game, i|
puts "第#{i}个游戏是#{game}"
end

数组的连接

games.join(','),这个方法其实很多语言都有,可以返回一个由逗号连接的、由数组每个元素顺序组成的字符串。

怎么判断该变量是否是数组

这个怎么判断呢???

很简单,还是运用 respond_to?

怎么用?

刚刚的 each 方法就可以!

games.respond_to?('each') && puts '这是一个数组!'

函数

普通函数

def sayHello
puts "Hello World."
end sayHello() # Hello World.
sayHello # Hello World.

这里可以看到,Ruby 的函数既可以带括号的调用,也可以直接调用。

传参的函数

def sayHello(name)
puts "Hello, #{name}."
end

解包参数

函数会自动解包传入的数组。

def foo(p1, p2, p3)
p p1 + p2 + p3
end foo [1, 2, 3]

注意,这种将数组解包的函数,如果传入的数组长度大于参数数量,那么会直接报错。

部分参数解包

传入的多余参数转化为数组。

def foo(base, *rest)
rest.each do |item|
base += item
end return base
end foo 1, 2, 3, 4, 5

*rest 参数可以不在末尾。

def foo(base, *rest, final)
p base
p rest
p final
end foo 1, 2, 3, 4, 5 # base 1, rest [2, 3, 4], final 5
foo 1, 2 # base 1, rest [], final 2
foo 1 # 报错

参数的默认值

def sayHello(name = 'world')
puts "Hello, #{name}."
end sayHello "啦啦啦"

传入一个散列

该形式必须提供默认值。

def sayHello(url: "", id: 0)
puts "#{url}?id=#{id}."
end sayHello url: "xxx", id: 5

这就类似于 JS 中的:

function foo({ a, b } = { a: 1, b: 1 }) {}

这种形式还可以直接传入一个散列,但是必须保证 key 类型是 Symbol 类型,String 或者其他类型都会导致报错:

h = {
:p1 => 100,
:p2 => 200
} h_err = {
'p1' => 100,
'p2' => 200
}

class

让我们来定义一个手机类:

class Phone
def initialize(brand = '苹果', name = '刘好', number = 15_527_782_945)
@brand = brand
@name = name
@number = number
end def call
puts "#{@name}使用#{@brand}手机,拨打了#{@number}的号码。"
end
end iPhone = Phone.new iPhone2 = Phone.new('三星', '王自如', 1123321)

与函数一样,class 实例化时调用 new 方法也不需要括号。

Ruby 管 @ 开头的变量叫做实例变量,@@ 开头的叫做类变量。但其实类似于 Java 的成员变量和静态成员变量。

但不同的是,Ruby 自带封装性。

实例变量默认外部不可以访问,需要我们自定义一下 getter/setter。

  • attr_accessor :xxx 为 getter/setter
  • attr_reader :xxx 为 getter
  • attr_writer :xxx 为 setter
class Game
attr_accessor :price
attr_reader :name
def initialize(name = "怪物猎人世界", price = 200)
@name = name
@price = price
end
end

class 下面有啥方法?

Phone.instance_methods(false)

这个方法,可以让我们知道该类下,有什么方法是我们自定义的。

对于上面写的 Phone 类,输出结果就会是:

call

就这么简单。

如果参数为 true 呢,则会显示所有的方法,包括自带的方法。

如何判断这个方法是否存在呢?

iphone = Phone.new
iphone.respond_to?("call")

respond_to? 这个方法可以判断该对象是否拥有某个方法,可以返回一个布尔值。

所以我们通常可以这么用:iPhone.respond_to?("call") && iPhone.call

(未完待续)

Ruby 趣学笔记(一)的更多相关文章

  1. Ruby 趣学笔记(二)

    Ruby 趣学笔记(二) 本文写于 2020 年 5 月 7 日 类的继承 之前忘记写了,Ruby 的继承写法是: class IPhone < Phone def initialize(id, ...

  2. 自导自演的面试现场,趣学MySQL的10种文件

    导读 Hi,大家好!我是白日梦!本文是MySQL专题的第 24 篇. 今天我要跟你分享的MySQL话题是:"自导自演的数据库面试现场--谈谈MySQL的10种文件" 换一种写作风格 ...

  3. junit浅学笔记

    JUnit是一个回归测试框架(regression testing framework).Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(Wh ...

  4. 沈逸老师ubuntu速学笔记(2)-- ubuntu16.04下 apache2.4和php7结合编译安装,并安裝PDOmysql扩展

    1.编译安装apache2.4.20 第一步: ./configure --prefix=/usr/local/httpd --enable-so 第二步: make 第三步: sudo make i ...

  5. 沈逸老师ubuntu速学笔记(1)--安装flashplayer,配置中文输入法以及常用命令

    开篇首先感谢程序员在囧途(www.jtthink.com)以及沈逸老师,此主题笔记主要来源于沈老师课程.同时也感谢少年郎,秦少.花旦等同学分享大家的学习笔记. 1.安装flash player ctr ...

  6. [2017.02.21] 《Haskell趣学指南 —— Learning You a Haskell for Great Good!》

    {- 2017.02.21 <Haskell趣学指南 -- Learning You a Haskell for Great Good!> [官网](http://learnyouahas ...

  7. 《趣学Python编程》

    <趣学Python编程> 基本信息 作者: (美)Jason Briggs 译者: 尹哲 出版社:人民邮电出版社 ISBN:9787115335951 上架时间:2014-2-21 出版日 ...

  8. 《Haskell趣学指南》

    <Haskell趣学指南> 基本信息 原书名:Learn You a Haskell for Great Good!: A Beginner's Guide 原出版社: No Starch ...

  9. 随学笔记 partAdded

    随学笔记: RectangularDropShadow为矩形对象添加阴影,DropShadowFilter可以为任意形状对象添加阴影. BorderContainer和Panel等容器使用的就是Rec ...

随机推荐

  1. 学习Haproxy (七)

    haproxy是个高性能的tcp和http的反向代理.它就是个代理.不像nginx还做web服务器 官网地址为www.haproxy.org nginx的优点和缺点 ? 1 2 3 4 5 6 7 8 ...

  2. read,readline,readlines的特点与区别

    1.read 读取全部文件 with open("test.text", "r",encoding='utf8') as f: print(f.read()) ...

  3. matlab二维插值--interp2与griddata

    二者均是常用的二维插值方法,两者的区别是, interp2的插值数据必须是矩形域(X,Y必须分别是单调向量),即已知数据点(x,y)组成规则的矩阵,或称之为栅格,可使用meshgid生成. gridd ...

  4. 从CSS盒子模型说起

    前言 总括: 对于盒子模型,BFC,IFC和外边距合并等概念和问题的总结 原文地址:从CSS盒子模型说起 知乎专栏:前端进击者 博主博客地址:Damonare的个人博客 为学之道,莫先于穷理:穷理之要 ...

  5. Web前端初级问题—ajax登录跳转登录实现

    当我们的用户进行系统登录时,用户名和密码的验证都是后端验证的.而且,用户登录状态也是要后端设置的,查询数据库后,用户名和密码正确,则在session中存储一个uuid,每个页面需要根据登录状态判断展示 ...

  6. IE中input标签密码框与文本框宽度不一样问题

    前言 在项目登录界面中有账户和密码的输入框,在Chrome中显示是正常的(本人使用的是Chrome浏览器,平时不用IE).等部署到客户的服务器上,访问时发现一个问题,在IE浏览器中文本框与密码框的宽度 ...

  7. 浅谈js本地图片预览

    最近在工作中遇到一个问题,就是实现一个反馈页面,这个反馈页面的元素有反馈主题.反馈类型.反馈内容.反馈人联系电话以及反馈图片.前端将这些反馈的元素POST给后台提供的接口:实现这个工作的步骤就是:页面 ...

  8. EMS已有用户分配邮箱方法

    案例任务:已有域用户"test100",为该用户分配邮箱. 分配邮箱前,使用"get-user"命令确认用户类型.域用户"test100"的 ...

  9. js知识梳理3:创建对象的模式探究

    写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...

  10. 基于Apache Hudi和Debezium构建CDC入湖管道

    从 Hudi v0.10.0 开始,我们很高兴地宣布推出适用于 Deltastreamer 的 Debezium 源,它提供从 Postgres 和 MySQL 数据库到数据湖的变更捕获数据 (CDC ...