本文概述
- 前言
- Ruby安装
- Ruby HelloWorld程序
- Ruby变量
- 数据类型
- Ruby字符串
- Ruby数字和数学
- Ruby获取用户输入
- Ruby数组
- Ruby散列表/哈希表/字典/键值对
- Ruby方法
- Ruby方法返回值
- Ruby条件语句
- Ruby Case表达式
- Ruby While语句
- Ruby For循环
- Ruby文件读写
- Ruby异常处理
- Ruby类和对象
- Ruby继承
- Ruby模块
- 模拟CocoaPods配置
- 总结
前言
要我说,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安装包下来,双击打开就可以像安装一般软件那样安装了,其中记得选上以下选项:
然后一直点下去,全部默认即可,等待一会就安装成功了。
安装成功后会弹出命令行窗口,在命令行中分别输入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编程就到这里了,学一遍以后忘了就不再学了,可以即时查,即时使用。