Ruby语言基础

ruby语言基础

1.ruby简介

编程界几大魔幻语言,c++JavaScriptrubyperl等,个个都是神奇而强大,好坏不一,魔幻的别称不是没来由。perl这辈子我是不会碰,c++JavaScript算是一家,学会了一种,另外一种过渡不算困难,c++是爱好。剩下就是ruby了,号称是要干死python,现在看来ruby其实已经半死不活。

本文就是针对ruby的,现学现卖,希望能够整理出一份比较容易入门的帖子。本文的角度是,假设已经掌握了一门语言,主要目的是快速掌握ruby的关键语言特性。因为你我的时间都很宝贵,不需要在语言语法上浪费过多的时间。

1.1.hello world

经典的例子,就是是hello world,ruby中一行语句就可以完成,和python类似。

# 这是一行,注释方法和python类似
puts 'hello world' # 括号可以省略

# p程序员专用 输出字符串时会带有引号,类似puts
p "hello world"

=begin
这是多行注释
puts有多个参数时,每个输出都会换行
print 只在最后添加换行
p 一般是给编程程序员使用
=end
print 'hello', 'world' # 等价于print('hello', 'world')
puts 'hello', 'world'

ruby中在<<之后,您可以指定一个字符串或标识符来终止字符串,且当前行之后直到终止符为止的所有行是字符串的值。

# 很ruby的用法,
print <<E # E要成对出现,也可以是其他单词或者字母
hello world!
hello wrold!
E
# 输出
hello world!
hello wrold!

# 您可以把它们进行堆叠,不过先后顺序是不能乱
print <<"foo", <<"bar"          
    hello foo.
foo
    hello bar.
bar

1.2.ruby之旅

1.2.1.顺序语句

定义变量的语法。

# 定义变量,和python一样
i = 1 # 整数
hi = 0xff # 16进制数
bi = 0b1011 # 二进制数

# 全局变量
$gi = 0
$gs = 'this is global string'

# 局部变量作用域,和python差不多
if true then
    if_local_var = 0
end
puts if_local_var # if语句内定义的变量依然可见

ruby语言是纯面向对象,连标准类型也是对象。

# 字符串
s = 'hello world' # 字符串
ss = "string value is #{i}" # 双引号可以通过变量格式化,有点类似python模板

# 下面字符串定义语法,很ruby
s = %q{hello world} # 同  s = 'hello world'
ss = %Q{string value is #{i}} # 同 ss = "string value is #{i}"
# 多行字符串定义
ss = %Q|first line
"second line"
|
puts ss # 输出多行 ,你可以使用{}、[]、||、<>、??、//、\\、;;等等都可以,不一定是{}

# 空值,nil不代表''
s = ''
if s == nil
    puts 's is null'
end

# 浮点数
f = 3.14
puts f.round # 3 四舍五入
puts f.ceil # 4 进位
puts f.to_i # 3 转换整数

其他语句的语法举例:

# 多重赋值
a, b, c = 1,2,3 # 定义变量a、b、c
a, b = b, a # 交换a和b的值
array = [1,3,4] # 定义数组
a, b, c = array # 数组解析到变量中

# 三元运算符?: 语句,和C++语法保持一致
max = (10 > 5) ? 10 : 5

# 常量,全部采用大写,如果改写会发出告警
PI = 3.14

# 基础的表达式 比如+ - * / % **
a = 1 * 2
a += 1 # 等价于a = a + 1

# 范围运算符
puts 1..3.to_a # [1, 2, 3]
puts 1...3.to_a # [1, 2]

# 数组与数组迭代
array = [1, 2, 3, 4]
array.each do |it|
    puts it
end
puts it # 注意,it生命周期已结束,it未定义

# 数组长度 length和size都是获取数组长度
nums = Array[1, 2, 3, 4,5]
puts "array size is: #{nums.length} or size: #{nums.size}"
puts "#{nums}"

# hash类型,类似json
hash = {"name" => 'ruby1', "age" => 20}
hash.each do | key, value |
    puts "key: #{key}, value: #{value}"
end
hash[:name] = 'ruby2' # 访问name节点,不能使用hash["name"]访问

1.2.2.条件语句

控制语句主要有条件、循环等,好消息ruby好像没有goto语句。

# 基本的条件语句:if 表达式用于条件执行。值 false 和 nil 为假,其他值都为真
i = 4
if i > 10 then
    puts 'i > 10'
elsif i > 5 then
    puts 'i > 5'
else
    puts 'i in else'
end

# if修饰符
puts 'pass' if 1 > 0
puts 'not ouput' if 0 > 0 # 条件不成立不会输出

# unless语句,与if相反,unless有存在的价值吗?
x = 1
unless x > 2
    puts "x <= 2"
else
    puts "x > 2"
end

# unlese修饰符
i = 0
puts 'get unless' unless i > 0

# case,这个确实有点丑
age =  5
case age
when 0 .. 2
    puts "baby"
when 3 .. 12
    puts "child"
when 13 .. 18
    puts "young"
else
    puts "adult"
end

# ruby没有with语句,可以自己定义一个

1.2.3.循环语句

循环语句主要有whiledountilforbreaknextredoretry等。

# while语句与while修饰符
a, b = 1, 10
while a < b do
    puts "a is #{a}"
    a += 1
end

a, b = 1, 10
begin
    puts "a is #{a}"
    a += 1 
end while a < b

# until语句
a, b = 1, 10
until a >= b do
    puts "a is #{a}"
    a += 1 
end

# until修饰符
a, b = 1, 10
begin
    puts "a is #{a}"
    a += 1 
end until a >= b

# for语句
for i in 0..10
    puts "i = #{i}"
end
puts i # i依然有定义,i = 10

#遍历数组
names = ['a', 'b']
for name in names
  p name
end

# each
(0..10).each do |ii|
    puts "ii = #{ii}"
end
puts ii # 此语句失败

# break
for i in 0..10
    if i > 3 then break end
    puts "i = #{i}"
end

# next if
for i in 0..10
    next if i < 3 # 如果i < 3就继续下次循环
    puts "i = #{i}"
end
# 等价于
for i in 0..10
    if i < 3 then next end
    puts "i = #{i}"
end

# redo语句
for i in 0..10
    if i < 3 then
        puts "i is #{i}"
        redo # 这里会出现死循环
    end
end

# retry语句已经废弃

# do语句
3.times do
    p 'times1'
end

# 用花括号代替 do end
3.times { p 'times2' }

3.times do |i|
    p "#{i + 1}times1"
end

3.times { |i|
    p "#{i + 1}times2"
}

name = ['a', 'b']
names.each do |name|
  p  name
end

1.2.3.异常语句

# 异常基本用法
begin
    p ii # ii未定义
rescue NameError
    # NameError是指定异常,如何不写,就是捕获所有异常
    p 'var ii is undefine'
ensure
    p 'must exec' # 无论是否有异常,一定会执行
end

# 主动抛出异常
raise Exception.new('this is exception')
raise RuntimeError.new('this is runtime exception')

# 异常隐藏问题,同大多数语言一致
begin
    p ii # ii未定义
rescue Exception => err
    p "you are here #{err}" # 会执行到这里
rescue NameError
   # 实际抛出NameError,被上面捕获拦截了,因为NameError是Exception的子类
    p 'var ii is undefine' 
end

1.2.3.函数

函数的基本定义:

# 定义一个方法
def first_method()
    puts 'this is first method'
end

# 带参数
def second_method(name, age=100)
    puts "name: #{name}, #{age}"
end
second_method('china')
second_method('earth',age=1000)
second_method(age=10000, name='sun') # 这里调用结果不是我们预期的,和python是有区别的
second_method(age:10000, name:'sun') # 这样调用也是不行的

# 括号可以省略
second_method 'china', 100
# 定义时候,也可以不用括号
def third_method name, age
    puts "name: #{name}, #{age}"
end
third_method 'sun', 10000

# 返回值 return
def return_one(a)
    return a * a
end
def return_two(a)
    return a * a, a ** 2
end
return_one(10)
a, b = return_two(10)

# 返回return,可以省略
def return_one(a)
    a * a # 这里省略了return,这很ruby
end
return_one(10)

函数的参数可变

# 可变参数函数
def sum(*element)
    ret = 0
    for i in 0...element.length
      ret += i
    end
    return ret
end
sum(1,2,3,4,5)

关键字参数,类似与python,不过python统一了关键字参数和非关键字参数用法。

def distance(x:0, y:0, z:0)
    return x**2 + y **2 + z **2
end

puts distance(z:1, x:2, y:3)
puts distance(1,2,3) # 语法错误

# 可变关键字参数
def distance(x:0, y:0, z:0, **kwags)
    a1 = x**2 + y **2 + z **2
    for v in kwags.values
        a1 += v ** 2
    end
    return a1
end
puts distance(x:1,y:2,z:3,m:4,n:5)

# 关键字参数和非关键字参数可以混用
def distance(x, y, z, **kwags)
    a1 = x**2 + y **2 + z **2
    for v in kwags.values
        a1 += v ** 2
    end
    return a1
end
puts distance(1,2,3,m:4,n:5)
puts distance(1,2,3,**{m:4,n:5})

函数的别名,取消函数定义、嵌套函数。

# 方法别名alias
alias mysum sum
mysum(1,2,3,4,5) # 调用新的别名方法

# 去除方法定义, 再调用sum和mysum都会出现方法未定义
undef mysum
# 嵌套函数
def outer_func()
    def inner_func()
        puts 'this is inner function'
    end

    inner_func()
    puts 'this is outer function'
end
outer_func()
inner_func() # 这里也可以调用内部函数
outer_func.inner_func() # 调用失败

# 取消定义
undef outer_func
inner_func() # 这里依然可以调用

lambda函数定义

# lambda函数
ff = lambda{|a,b| return a * b}
ff.call(10,20) # 这里ff调用需要加上.call

ruby由于函数参数都是动态类型,所以也就没有了函数重载能力。这一点和python比较类似。另外,ruby语言层面没有支持装饰器。

1.2.3.类

用户可以通过类创建自定义类型,关键字class和大多数语言一样的。我们定义一个类Student,有两个属性name和age,代码如下:

class Student
    # attr_accessor标示读写,只读attr_reader、只写attr_writer
    attr_accessor :name
    attr_accessor :age

    # 构造函数 initialize,接受两个参数
    def initialize(name, age)
        # 实例变量亿@开头
        @name=name
        @age=age
    end
end

s = Student.new('ssss', 100)
puts s.name
s.name = 'ssss2'
puts s.name
s.age = 200
puts s.age

类型定义,共有,私有和保护方法

class MyClass
    def private_method()
        puts 'private method'
    end

    def protected_method()
        puts 'protected method'
    end

    def public_method()
        puts 'public method'
    end

    private :private_method
    protected :protected_method
end

mc = MyClass.new()
mc.public_method()

# run error
mc.protected_method()
mc.private_method()

类定义静态属性,需要定义相应的方法,外部才能够访问。默认情况下,静态属性是私有的。

class StaticClass
    @@s_int = 0
    @@s_str = 'hello'

    def s_int
        @@s_int
    end

    def s_str
        @@s_str
    end

    def self.s_str
        @@s_str
    end

    # 定义类方法
    def StaticClass.static_method()
        puts 'this is static method'
    end
end

puts StaticClass.new.s_int
puts StaticClass.s_str
puts StaticClass.static_method()
# 静态方法,对象不能调用
puts StaticClass.new.static_method()

类继承

class Base
    def show
        puts 'show method from base'
    end

    def message
        puts 'message from base'
    end
end

class Child < Base
    def message
        puts 'message from child'
    end
end

base = Base.new
child = Child.new

base.message()
base.show()
child.message()
child.show()

# 关于多态,ruby是动态语言,天生就支持类型的多态

调用父类的构造方法

class Base1
    def initialize(name, age)
        puts "base init: #{name} #{age}"
    end
end

class Child1 < Base1
    def initialize(name, age, phone)
        super(name, age)
        puts "child init #{phone}"
    end
end

child = Child1.new('haha', 100, '136')

2.词法结构

3.基础类型

4.表达式

5.语句

6.字符串

7.数组

8.函数

9.类

10.模块

11.标准库

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 任何语言的核心所描述的都是这门语言在最基本的层面上如何工作,涉及语法、操作符、数据类型 以及内置功能,在此基础之上...
    sayhelloworld阅读 221评论 0 1
  • 原文 如果你是一个 Ruby 开发者, 并且想要开始使用 Go, 这篇文章可以帮助你入门. 在这篇文章里, 我们会...
    冲云直树阅读 170评论 0 0
  • Java概述 何为编程 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。 ...
    小饭_317b阅读 112评论 0 0
  • 本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入...
    小小不懂11阅读 3,406评论 2 30
  • 一、快捷键 ctr+b 执行ctr+/ 单行注释ctr+c ...
    o_8319阅读 5,779评论 2 16