Ruby编程语言快速上手[学习笔记]

2021年3月8日16:44:47 发表评论 911 次浏览

本文概述

前言

Ruby编程语言学习笔记

要我说,Ruby的语法真是奇奇怪怪,包括Groovy、Python等一些脚本语言。这些脚本语言通常都带有语法糖,这糖好不好吃要看个人是否习惯,对于我个人来说不大习惯,因为我是强类型语言入门的。

本文围绕Ruby编程快速入门,这是为了什么呢?解决配置文件的问题,因为发现有些配置是使用Ruby的,例如Podfile,如果没有发现这文件就是一个Podfile脚本,那可就慌了,奇奇怪怪的语法,常常可能引起一些奇怪的问题,而且写配置也不大方便——所以打算快速学一下Ruby。

如果你有过其它一门或几门语言的经验,学Ruby并不难,一天就可以上手了。我也是打算一天搞定Ruby,当然达不到精通,但是足够了,毕竟我的主编程不是用Ruby。

另外我发现Ruby的相关东西像JavaScirpt一般复杂,Bundler、Rubygems、RVM各种东西,JS也是有很多这中东西。有时觉得很没必要,为什么不使用一个集成构建和依赖管理于一身的工具呢?期待有这样的工具,不然使用类似Ruby和JS开发简直比Java、C++还难。

好了,吐槽完了,开始Ruby编程快速上手学习,那么第一步是什么?当然是安装Ruby SDK和运行环境了。

Ruby安装

Windows平台Ruby编程到这里下载安装:https://rubyinstaller.org/downloads/,至于Mac或其它平台,你可以去官网找找看:http://www.ruby-lang.org/en/。

引用官网的下载说明:如果您不知道要安装哪个版本,并且正在开始使用Ruby,我们建议您使用Ruby+Devkit 2.7.X (x64)安装程序。它提供了最多的兼容gem,并在Ruby的同时安装了MSYS2 Devkit,因此可以立即编译带有c扩展的gem。仅当必须使用自定义32位本地dll或COM对象时,推荐使用32位(x86)版本。

下载Installer安装包下来,双击打开就可以像安装一般软件那样安装了,其中记得选上以下选项:

Ruby安装说明

然后一直点下去,全部默认即可,等待一会就安装成功了。

安装成功后会弹出命令行窗口,在命令行中分别输入1、2、3并等待相关处理,完成后关闭窗口。

验证ruby:打开cmd命令行,输入ruby -v查看ruby的版本信息,正常显示即表示安装成功。

Ruby HelloWorld程序

Ruby的源文件为.rb文件,使用ruby *.rb命令可以运行一个ruby脚本,下面是一个简单的例子:

print "Hello" # 不换行
puts 'Ruby' # 换行
puts 'Groovy' # 换行
puts '''1st line
2nd line
3rd line
'''

print和puts函数都是打印函数,区别是前者输出不换行,后者输出带换行。你可以看到ruby中的函数调用是不需要括号的,也不需要语句后面的分号,而且Ruby中的字符串同样有三种形式:单引号、双引号和三引号(和其它流行的脚本语言类似)。

Ruby变量

Ruby变量的声明方式如下:

variable_name = value

下面是使用的例子:

name = 'BIN'
age = 90
height = 1.83
puts(name)
puts age.to_s + "\n" + height.to_s

数值不能使用“+”直接连接字符串,因为“+”在Ruby中类似C++的运算符重载,它是一个函数,这里数值转换为字符串使用to_s函数。

数据类型

name = "Mike"  # String字符串类型
puts name.class # String
age = 90 # Integer整数类型
puts age.class
gpa = 3.14 # Float
puts gpa.class
isSet = true # Boolean - TrueClass
puts isSet.class
obj = nil # NilClass
puts obj.class

Ruby字符串

name = "Tom"
puts 'Hello ' + name # 字符串可直接连接
puts name.upcase  # 大写, 无参数可以省略括号
puts name.downcase() # 小写, 可使用括号
puts name.length  # 字符串长度
puts name.include? 'o' # 判断字符串是否包含某些字符
puts name.include?("m") # include?是一个函数
puts name[2].upcase # 可使用[]访问字符串元素
puts name[1,2] # 范围
puts name.index("om") # 查找字符索引位置

Ruby数字和数学

puts 12 # int
puts -3.14 # float
puts 2 + 9
# puts 4 + 'Name' # Wrong
puts 4.to_s + "Name" # Right
puts 2**3 # 指数 2^3
puts '++++++++++++++'

number = -78.65
puts number.abs  # 绝对值
puts number.ceil
puts number.floor
puts Math.sqrt(49)
puts Math.log(3)
puts '++++++++++++++'

puts 12/4
puts 1/2  # 0
puts 1/2.0 # 0.5

Ruby获取用户输入

var = gets.to_s  # get string from user input
puts var.class # String
puts var

var = gets.to_i # integer
puts var.class
puts var

var = gets
puts var.class
puts var

Ruby数组

array = [23, 34, 21, 'Name', 12.34, true, nil]
puts array
puts array[2]
puts array.size
puts array[-1]
puts array[-2]
puts array[0, 2]
puts "+++++++++++"

array[0] = 90
puts array[0]
puts array.reverse
puts array.include? 34
puts "+++++++++++"

ma = Array.new
ma[0] = 8
ma[3] = 3
puts ma
puts ma.length

Ruby散列表/哈希表/字典/键值对

map = {1 => "111", 2 => "222", 
    3 => "333", "ok" => "Hume",
    :str => "Kant"}
puts map
puts map["ok"]
puts map[1]
puts map[:str]

map[1] = "11111111"
puts map[1]

Ruby方法

def hello(index = 0, from = "HELL")
    puts "[" + index.to_s + "] hello funciton from " + from
end

hello 12, 'Tom'
hello 89
hello

Ruby方法返回值

# 01
def mul(num)
    num * num * num 
    # 使用函数最后一个表达式的值作为返回值
end

puts mul 3

# 02
def div(num) 
    -80
end

# 03
puts div 12

# 04, 返回值可返回多个值,作为数组
def f
    return 1, 2
end
puts f
puts f()[1]

Ruby条件语句

num = 90
# 01
if(num < 9)
    puts "num < 9"
else
    puts "num > 9"
end
puts " "

# 02
if num == 90
    puts "num = 90"
end
puts " "

# 03
if num == 89
    puts "num = 89"
elsif num > 100 or num > 9999
    puts "num > 100 or num > 9999"
elsif num < 999 and num > 1
    puts "num < 999 and num > 1"
end
puts " "

# 04
isGril = false
if !isGril
    puts "not a girl"
end
puts " "

# 05
def max(a, b)
    if(a > b)
        return a
    elsif a < b
        return b
    else
        a
    end
end
puts max 23, 34
puts max 23, 23
puts max 10, 100

Ruby Case表达式

test = 9
case test
when 8
    puts test    
when 9
    puts "equals 9"
else
    puts "can not find"
end
str = "111"
case str
when "11111"
    print "-> 11111"
when "1111"
    print "*> 1111"
when "111"
    print "&> 111"
else
    print "invalid string"
end

Ruby While语句

i = 1
count = 0
while i < 100
    count = count + i
    i += 1
    # i++ => wrong
end
puts count

Ruby For循环

array = [12, 234, 432, 97, 93]
for n in array
    puts n
end

array.each do |item|
    print item.to_s + "  "
end

for n in 1..10
    puts n
end

4.times do |i|
    puts i
end

Ruby文件读写

# 1. read file
File.open('names.txt', 'r') do |file|
    # puts file
    # puts file.read
    # puts file.readline
    file.readlines.each do |line|
        puts "*** " + line.chomp + " ***"
    end
end

file = File.open("names.txt", 'r')
puts file.read
file.close

# 2. write file
File.open("names.txt", "a") do |file|
    file.write("\nHeger, Russell")
end

Ruby异常处理

begin
    num = 1 / 0
rescue ZeroDivisionError => exception
    puts exception
end

begin
    1 / 0
rescue => exception
    puts "error: " + exception.to_s
end

begin
    1 / 0
rescue
    puts "error"
end

Ruby类和对象

class MyClass
    attr_accessor :name, :age
    
    def hello
        puts "hello " + @name
    end
    
end

obj = MyClass.new()
obj.name = "Poter"
obj.age = 90
obj.hello
puts ""

class Book
    # 实例属性
    attr_accessor :title, :author
    @rate = 0 # 实例属性
    @@counter = 0 # 类属性(静态)
    
    # 构造函数
    def initialize(title, author)
        @title = title
        @author = author
        @rate = title.length
    end

    # 实例方法
    def hello
        @@counter += 1
        puts "----" + @@counter.to_s + "----"
        print @title + " ["
        puts @author + "]  - " + @rate.to_s
        puts ""
    end
end
b1 = Book.new("A Treatise of Human Nature", "Hume")
b1.hello
b2 = Book.new("Critique of Pure Reason", "Kant")
b2.hello

Ruby继承

class Animal
    
    def initialize(name, weight)
        @name = name
        @weight = weight
    end
    
    def run
        puts @name + " is running..."
    end

    def rest
        puts @name + " is sleeping..."
    end

end

animal = Animal.new("Horse", 21)
animal.run
animal.rest

class Human < Animal
    def run
        puts @name + " is walk..."
    end
end

human = Human.new("Tom", 20)
human.run
human.rest

Ruby模块

module Tools

    def hello
        puts "hello ruby"
    end

end

require_relative "module_file.rb"
include Tools
Tools.hello

模拟CocoaPods配置

下面是CocoaPods的一般性配置:

source 'https://github.com/CocoaPods/Specs.git'

target 'Demo' do
    pod 'Mantle', '~> 1.5.1'
    pod 'SDWebImage', '~> 3.7.1'
    pod 'BlocksKit', '~> 2.2.5'
    pod 'SSKeychain', '~> 1.2.3'
    pod 'UMengAnalytics', '~> 3.1.8'
    pod 'UMengFeedback', '~> 1.4.2'
    pod 'Masonry', '~> 0.5.3'
    pod 'AFNetworking', '~> 2.4.1'
    pod 'Aspects', '~> 1.4.1'
end

由上面的Ruby学习,你可以知道source、target和pod其实都是一个方法/函数,而这些函数传参都可以省略括号,do-end是一个无参block(或类似闭包)。对以上代码的分析如下:

  • source是一个函数,用于配置源,参数是一个URL字符串。
  • target有两个参数,用于配置构建目标,第一个参数是构建目标的名称,第二个参数是一个block或闭包,用于详细配置该构建。
  • pod有两个参数,第一个参数指定pod的名称,第二个参数是pod的版本。

在Ruby中,给函数传参可以不使用括号,多个参数使用逗号隔开,函数的参数若有block或闭包,则最后一个参数为block,并且在传参的时候不需要使用逗号隔开(target的第二个参数是block,不使用逗号隔开)。

下面我们来模拟Podfile,首先是使用端(类似CocoaPods对配置文件的处理):

$config = {}

def source(url)
    $config['source'] = url
end

def target(target) 
    targets = $config['targets']
    targets = [] if targets == nil
    targets << target
    $config['targets'] = targets
    yield if block_given?
end

def pod(pod, version)
    pods = $config['pods']
    pods = [] if pods == nil
    podinfo = {:pod => pod, :version => version}
    pods << podinfo
    $config['pods'] = pods
end

def platform(platform, version)
    pf = $config['platform']
    pf = :osx if pf == nil
    pf = platform if platform
    v = "8.0" if version == nil
    v = version if version
    $config['platform'] = {:platform => pf, :version => v}
end

podfile = File.read './Podfile'
eval podfile
puts $config

首先是定义了一个全局变量,全局变量要使用$开头,用于储存全局配置信息。

  • 然后预定义一些函数。
  • 接着读取用户的Podfile文件内容,eval函数可以将传入的字符串当做Ruby代码来执行。
  • 最后打印全局配置信息。

下面是Podfile配置文件内容:

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, "9.0"

target 'Demo' do
    pod 'Mantle', '~> 1.5.1'
    pod 'SDWebImage', '~> 3.7.1'
    pod 'BlocksKit', '~> 2.2.5'
    pod 'SSKeychain', '~> 1.2.3'
    pod 'UMengAnalytics', '~> 3.1.8'
    pod 'UMengFeedback', '~> 1.4.2'
    pod 'Masonry', '~> 0.5.3'
    pod 'AFNetworking', '~> 2.4.1'
    pod 'Aspects', '~> 1.4.1'
end

总结

OK,关于Ruby编程和CocoaPods的配置又差不多了,借助CocoaPods的参考文档,其文档阅读基本没问题了。

总结一些脚本语言,发现其最大的特色就是语法糖:该语言定义了一些特别或语义化的语法,如果比较习惯强类型编程,可能对这个不大习惯。但是归结起来还是离不开编程的核心,例如内存模型、数据结构和算法,就语言上也还是数据类型、条件循环语句、函数/方法、类或接口等。

Ruby编程就到这里了,学一遍以后忘了就不再学了,可以即时查,即时使用。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: