概述
运算符
- 运算符
运算符 | 说明 |
---|---|
+ | |
- | |
* | |
/ | |
% | |
** | 求幂 |
== | |
=== | ???case..when语句中使用,一般不在外部使用??? |
!= | |
> | |
< | |
>= | |
<= | |
<=> | 返回参数比较的结果,0/1/-1 |
= | |
+= | |
-= | |
*= | |
/= | |
%= | |
**= | |
& | |
| | |
^ | 异或 |
~ | 取反 |
>> | |
<< | |
&& | ???同and??? |
|| | ???同or??? |
! | ???同not??? |
and | |
or | |
not | |
? : | |
. | Array.size |
.. | 1..5 ==> 1-5 |
… | 1…5 ==> 1-4 |
:: | Net::HTTP |
2. 一些判断的方法
eql?——判断值对象是否相等
equal?——判断对象ID是否相等
defined?
```
#判断变量是否定义
foo = 42
defined? foo # => "local-variable"
defined? $_ # => "global-variable"
#判断方法是否定义
defined? puts # => "method"
defined? puts(bar) # => nil (bar is not defined here)
defined? unpack # => nil (not defined here)
#判断块是否被传递
defined? yield # => "yield" (if there is a block passed)
defined? yield # => nil (if there is no block)
```
3. 运算符重载
不能被重载的运算符
= .. … ?: :: && || not and or
重载二元运算符
重载二元运算符时,常把参数名定义为other
在方法内创建当前类的对象时,不能直接写类名,因为直接写类名会创建确定的类,而用self.class,创建的类就是实际调用new方法时的类
class Point attr_reader :x, :y def initialize( x = 0, y = 0 ) @x, @y = x, y end def inspect "#{x}, #{y}" end def +(other) self.class.new( x + other.x, y + other.y ) end def -(other) self.class.new( x - other.x, y - other.y ) end end point0 = Point.new(3, 6) point1 = Point.new(1, 8) p point0 #==> 3, 6 p point1 #==> 1, 8 p point0 + point1 #==> 4, 14 p point0 - point1 #==> 2, -2
作为程序运行结果输出,用to_s方法;内部调试时,用inspect方法
重载一元运算符
可以重载的一元运算符:+ - ~ !
重载时,以+@ -@ ~@ !@命名
class Test def -@ self.class.new(-x, -y) end end
重载下标方法
class Point def [](index) case index when 0 x when 1 y else p "Error" end end def []=(index, val) case index when 0 self.x = val when 1 self.y = val else p "Error" end end end point = Point.new(3, 6) p point[0] #==> 3 p point[1] = 2 #==> 2 p point[1] #==> 2 p point[2] #==> 错误
异常
异常处理
begin 可能会发生异常的处理 rescue => ex #异常对象 发生异常时的处理 ensure 不管是否发生异常都希望之星的处理 end
发生异常时被自动赋值的变量
$!——最后发生的异常(异常对象)
$@——最后发生异常的位置信息
异常对象的方法
class——异常的种类
message——异常消息
backtrace——$@ == $!.backtrace
简写
# 如果整个方法或类都捕获异常的话,可以省略begin~end,直接写rescue或ensure部分 def foo process rescue 异常处理 ensure 后处理 end
重试
begin
process
rescue
sleep 10
retry #==> 发生异常时,重复执行process
end
rescue修饰符
表达式1 rescue 表达式2
如果表达式1发生异常,表达式2的值会成为整体表达式的值,等价于
begin 表达式1 rescue 表达式2 end
指定需要捕获的异常
用多个rescue分开处理
begin process1 rescue Exception1, Exception2 => 变量1 process2 rescue Exception3, Exception4 => 变量3 process3 rescue => 变量3 process4 end
异常类
Exception
|
|==========SystemExit
|==========NoMemoryError
|==========SignalException
|==========ScriptError
|==========|==========LoadError
|==========|==========SyntaxError
|==========|==========NotImplementedError
|==========StandardError
|==========|==========RuntimeError
|==========|==========SecurityError
|==========|==========NameError
|==========|==========|==========NoMethodError
|==========|==========IOError
|==========|==========|==========EOFError
|==========|==========SystemCallError
|==========|==========|===============Errno:EPERM
|==========|==========|===============Errno:ENOENT程序默认捕获StandardError类及其子类的异常
自己定义异常时,一般先定义继承StandardError的新类,然后再继承这个类
MyError = Class.new(StandardError) MyError1 = Class.new(MyError) MyError2 = Class.new(MyError) MyError3 = Class.new(MyError) MyError4 = Class.new(MyError) begin process rescue process1 end
主动抛出异常
raise 方法——主动抛出异常
raise message
抛出RunTimeError异常,把message传给异常对象
raise 异常类
抛出指定的异常
raise 异常类,message
抛出指定的异常, 把message传给异常对象
raise
在rescue外时,抛出RunTimeError
在rescue中时,再次抛出最后一次发生的异常
块
块就是在调用方法时,能与参数一起传递的多个处理的集合
块的使用
循环
实现了循环处理的方法,称为迭代器
sum = 0 hash = { "a"=>1, "b"=>2, "c"=>3, "d"=>4 } hash.each do |pair| sum += pair[1] #==> 用pair表示散列,pair[0] = key, pair[1] = value end hash.each do |key, value| sum += value end
隐藏常规处理
#确保后处理被执行 File.open("XXX") do |file| file.each_line do |line| print line end end #如果open失败,open方法会自动调用close,不用手动close
替换部分算法
array = ["Ruby", "Perl", "Python", "PHP"] sorted = array.sort p sorted #==> ["PHP", "Perl", "Python", "Ruby"] array = ["Ruby", "Perl", "Python", "PHP"] sorted = array.sort{ |a, b| a <=> b } #==> 将负责比较的块变量传递给sort方法 p sorted #==> ["PHP", "Perl", "Python", "Ruby"]
ary = %w( Ruby is a open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write ) call_num = 0 sorted = ary.sort do | a, b | call_num += 1 a.length <=> b.length end p "排序结果 #{sorted}" p "数组的元素数量 #{ary.length}" #==> "数组的元素数量 28" p "调用块的次数 #{call_num}" #==> "调用块的次数 91" #用sort_by方法将每个元素在块中调用一次,然后根据结果做排序处理 sorted = ary.sort_by{ |item| item.length } p sorted
定义带块的方法
执行块
def myloop while true yield end end
传递块参数,获取块的值
def total(from, to) result = 0 from.upto(to) do | num | if block_given? #==> 判断是否有块参数传递进来 result += yield(num) else result += num end end return result end p total(1, 10) #==> 55 p total(1, 10){ |num| num ** 2} #==> 385
def block_args_test yield() yield(1) yield(1, 2, 3) end p "通过|a|接收块变量" block_args_test do |a| p [a] end #==> [nil] #==> [1] #==> [1] p "通过|a, b, c|接收块变量" block_args_test do |a, b, c| p [a, b, c] end #==> [nil, nil, nil] #==> [1, nil, nil] #==> [1, 2, 3] p "通过|a|接收块变量" block_args_test do |*a| p [a] end #==> [[]] #==> [[1]] #==> [[1, 2, 3]]
控制块的执行
n = total(1, 10) do |num| if num == 5 break end num end p n #==>nil #在块中使用break,程序马上返回到调用块的地方,之前的结果会被忽略掉 n = total(1, 10) do |num| if num % 2 != 0 next 0 end num end
将块封装为对象
hello = Proc.new do |name| p "Hello, #{name}" end hello.call("David") hello.call("Wang")
#将块从一个方法传递给另一个方法时,会通过变量将块作为Proc对象接收 #在方法定义时,如果末尾的参数使用“&参数名”的形式,则自动把块封装为Proc对象 #Proc参数一定要在所有参数之后,也就是方法中的最后一个参数 def total2(from, to, &block) result = 0 from.upto(to) do |num| if block result += block.call(num) else result += num end end return result end
局部变量与块变量
- 块内部的命名空间与外部是共享的
x = 1 y = 1 ary = [1, 2, 3] ary.each do |x| y = x #==> x值块的局部变量 #==> 块内部,可以引用外部的局部变量y end
最后
以上就是甜美彩虹为你收集整理的Ruby基础教程(四)——运算符、异常、块运算符异常块的全部内容,希望文章能够帮你解决Ruby基础教程(四)——运算符、异常、块运算符异常块所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复