语句结束与变量命名

ruby只要将每条语句放在单独的一行上,就不需要在语句末尾使用分号。
Ruby使用了一个约定来帮助它区分名称的用法:名称的第一个字符表示名称的使用方式。

  • 局部变量、方法参数和方法名称都应该以小写字母或下划线开头。
  • 全局变量以美元符号($)为前缀
  • 实例变量以“at”符号(@)开头。
  • 类变量以两个“at”符号(@@)开头。

方法

irb(main):118:1* def numSum(nums)
irb(main):119:1*   result=0
irb(main):120:2*   nums.length.times{|n|
irb(main):121:2*     result+=nums[n]
irb(main):122:1*   }
irb(main):123:1*   return result
irb(main):124:0> end
=> :numSum
irb(main):125:0> numSum([11,22,66,7])
=> 106
irb(main):126:0> numSum([11,22])
=> 33
irb(main):127:0> 

#!/usr/bin/ruby
def numSum(nums)
   result=0
   nums.each do |n|
    result+=n
   end
   return result
end
puts numSum([1,2,3,4,5,6,7,8])

Ruby是一种真正的面向对象语言。你所操纵的一切都是一个对象,而这些操纵的结果本身就是对象。
Ruby中,这些对象是通过调用构造函数来创建的,构造函数是一种与类相关联的特殊方法。标准构造函数称为new。

书名:ruby指南,价格:69.23,库存:50 ,销售额:0.0
书名:ruby指南,价格:69.23,数量:4 ,销售额:276.92
书名:ruby指南,价格:69.23,库存:46 ,销售额:276.92
书名:ruby指南,入库20
书名:ruby指南,价格:69.23,库存:66 ,销售额:276.92
书名:ruby指南,价格:60.730000000000004,库存:66 ,销售额:276.92
#!/usr/bin/ruby

class Book
    attr_accessor :price
    def initialize(name="",price=0.0,stock=0)
        @name=name
        @price=price
        @stock=stock   
        @salesVolume = 0.0
    end
    def sayInfo()
        puts "书名:#{@name},价格:#{@price},库存:#{@stock} ,销售额:#{@salesVolume}"
    end
    def getTotalPrice()
         return @price*@stock
    end
    def addStock(count=0)
         @stock+=count
         puts "书名:#{@name},入库#{count}"
    end
    def sellBook(count=0)
         if count<=@stock
             @stock-=count
             @salesVolume+=count*@price
             puts "书名:#{@name},价格:#{@price},数量:#{count} ,销售额:#{@salesVolume}"
         else
            puts "请检查卖出数量真实性"
         end
     end
   end

myBook=Book.new("ruby指南",69.23,50)
myBook.sayInfo()
myBook.sellBook(4)
myBook.sayInfo()
myBook.addStock(20)
myBook.sayInfo()
myBook.price-=8.5
myBook.sayInfo()

#!/usr/bin/ruby

class Book
    attr_accessor :price
    def initialize(name,price=0.0,stock=0)
       if name.nil?  or name.lstrip==""
           puts "请检查书名。"
       end
        @name=name
        @price=price
        @stock=stock   
        @salesVolume = 0.0
    end
    def sayInfo()
        puts "书名:#{@name},价格:#{@price},库存:#{@stock} ,销售额:#{@salesVolume}"
        if @stock==0
           puts "书没有库存了,尽快进货"
        elsif @salesVolume==0
           allPrice=getTotalPrice()
           puts  "还有价值#{allPrice}的书要卖,加油卖书噢~"
        end      
    end
    def getTotalPrice()
         return @price*@stock
    end
    def addStock(count=0)
         @stock+=count
         puts "书名:#{@name},入库#{count}"
    end
    def sellBook(count=0)
         if count<=@stock
             @stock-=count
             @salesVolume+=count*@price
             puts "书名:#{@name},价格:#{@price},数量:#{count} ,销售额:#{@salesVolume}"
         else
            puts "请检查卖出数量真实性"
         end
     end
   end
myBook=Book.new("    ",69.23,50)
myBook=Book.new(nil,69.23,50)
myBook=Book.new("ruby指南",69.23,50)
myBook.sayInfo()
myBook.sellBook(4)
myBook.sayInfo()
myBook.addStock(20)
myBook.sayInfo()
myBook.price-=8.5
myBook.sayInfo()
请检查书名。
请检查书名。
书名:ruby指南,价格:69.23,库存:50 ,销售额:0.0
还有价值3461.5的书要卖,加油卖书噢~
书名:ruby指南,价格:69.23,数量:4 ,销售额:276.92
书名:ruby指南,价格:69.23,库存:46 ,销售额:276.92
书名:ruby指南,入库20
书名:ruby指南,价格:69.23,库存:66 ,销售额:276.92
书名:ruby指南,价格:60.730000000000004,库存:66 ,销售额:276.92

__FILE__ 是一个魔法值,它存有现在运行的脚本文件的名字。$0 是启动脚本的名字。 代码里的比较结构的意思是 “如果这是启动脚本的话…” 这允许代码作为库调用的时候不运行启动代码, 而在作为执行脚本的时候调用启动代码。

#!/usr/bin/ruby

class Book
    attr_accessor :price
    def initialize(name,price=0.0,stock=0)
       if name.nil?  or name.lstrip==""
           puts "请检查书名。"
       end
        @name=name
        @price=price
        @stock=stock   
        @salesVolume = 0.0
    end
    def sayInfo()
        puts "书名:#{@name},价格:#{@price},库存:#{@stock} ,销售额:#{@salesVolume}"
        if @stock==0
           puts "书没有库存了,尽快进货"
        elsif @salesVolume==0
           allPrice=getTotalPrice()
           puts  "还有价值#{allPrice}的书要卖,加油卖书噢~"
        end      
    end
    def getTotalPrice()
         return @price*@stock
    end
    def addStock(count=0)
         @stock+=count
         puts "书名:#{@name},入库#{count}"
    end
    def sellBook(count=0)
         if count<=@stock
             @stock-=count
             @salesVolume+=count*@price
             puts "书名:#{@name},价格:#{@price},数量:#{count} ,销售额:#{@salesVolume}"
         else
            puts "请检查卖出数量真实性"
         end
     end
   end
   
   
if __FILE__ == $0
	myBook=Book.new("    ",69.23,50)
	myBook=Book.new(nil,69.23,50)
	myBook=Book.new("ruby指南",69.23,50)
	myBook.sayInfo()
	myBook.sellBook(4)
	myBook.sayInfo()
	myBook.addStock(20)
	myBook.sayInfo()
	myBook.price-=8.5
	myBook.sayInfo()
end


encoding与输出

#!/usr/bin/ruby
#encoding:UTF-8
print "你好,世界\n"
puts "你好,世界"

  • encoding通常可以指定GBK或UTF-8
  • puts输出换行符。
  • print 输出一行,不换行。
  • 还 一个p,输出对象内容
  • 单引号原样输出,而双引号可以处理转义、变量内插等。
[maisipu@fedora learn]$ /bin/sh /tmp/geany_run_script_WLZ361.sh
你好,
世界
你好,
世界
"你好,\n世界\n"
你好\n世界\n
x=1213
x=#{x}\n

#!/usr/bin/ruby
#encoding:UTF-8
print "你好,\n世界\n"
puts "你好,\n世界\n"
p "你好,\n世界\n"
puts '你好\n世界\n'
x=1213
print "x=#{x}\n"
print 'x=#{x}\n'

case

#!/usr/bin/ruby
#encoding:UTF-8
puts "请输入一个数"
num=gets.chomp.to_i
case 
when (num in 1..50) then
    puts ">=1 and <=50"
when (num in 51...100) then
    puts ">=51 and <=100"
when (num>=100) then
    puts ">=100"
else
    puts "<=1"
end

[maisipu@fedora learn]$ 
[maisipu@fedora learn]$ /bin/sh /tmp/geany_run_script_FNXU61.sh
请输入一个数
12
>=1 and <=50


------------------
(program exited with code: 0)
[maisipu@fedora learn]$ 
[maisipu@fedora learn]$ /bin/sh /tmp/geany_run_script_C40B71.sh
请输入一个数
66
>=51 and <=100


------------------
(program exited with code: 0)
[maisipu@fedora learn]$ 
[maisipu@fedora learn]$ /bin/sh /tmp/geany_run_script_0KP561.sh
请输入一个数
991
>=100


------------------
(program exited with code: 0)
[maisipu@fedora learn]$ 
[maisipu@fedora learn]$ /bin/sh /tmp/geany_run_script_PBHY61.sh
请输入一个数
0
<=1


#!/usr/bin/ruby
#encoding:UTF-8
puts "请输入一个数"
num=gets.chomp.to_i
case num
when 1..50 then
    puts ">=1 and <=50"
when  51...100 then
    puts ">=51 and <=100"
else
    puts "异常值"
end

异常

#!/usr/bin/ruby 
#encoding:UTF-8
x=100
begin
   result=x/0
rescue
   puts "除0错误"
end

除0错误
#!/usr/bin/ruby 
#encoding:UTF-8
x=100
begin
   result=x/0
rescue =>err
   puts "除0错误" 
   puts err
ensure 
   puts "除法运算结束"
end
除0错误
divided by 0
除法运算结束


Class Exception及其子类

用于begin...end中的rescue和ernel#raise 中。
Exception对象携带有关异常的信息:

  • 其类型(异常的类)。
  • 可选的描述性消息。
  • 可选的回溯信息。
  • Exception的一些内置子类有额外的方法:例如,NameError#name

默认的异常类

有两个Ruby语句具有默认的异常类:
raise:默认为RuntimeError。
rescue:默认为StandardError。
当已经引发但尚未处理异常时(rescue,ensure,at_exit和END块),将设置两个全局变量:

$! 包含当前异常。

$@包含其回溯。

#!/usr/bin/ruby 
#encoding:UTF-8
x=100
begin
   result=x/0
rescue Exception=>err
   puts "错误:#{err}" 
   puts "当前异常#{$!}" 
   puts "回溯:#{$@}"
ensure 
   puts "除法运算结束"
end
#!/usr/bin/ruby 
#encoding:UTF-8
x=100
begin
   result=x/0
rescue StandardError=>err
   puts "错误:#{err}" 
   puts "当前异常#{$!}" 
   puts "回溯:#{$@}"
ensure 
   puts "除法运算结束"
end
错误:divided by 0
当前异常
回溯:["learn4.rb:5:in `/'", "learn4.rb:5:in `<main>'"]
除法运算结束

自定义异常类

为了提供附加或替代信息,程序可以创建从内置异常类派生的自定义异常类。

#!/usr/bin/ruby 
#encoding:UTF-8

class Score
       class Error <::StandardError
            def initialize()
                 @message = "成绩分数异常"
            end 
            def sayErr()
                puts @message
            end     
       end 
end

puts "请输入成绩:"
score=gets.chomp.to_i
begin
   case score
        when 0...60 
             puts "不及格"
        when 61..80
             puts "良"
        when 81..99
             puts "优秀"
        when 100
             puts "满分"
        else
             raise Score::Error.new
   end
rescue Score::Error=>err
        err.sayErr()
ensure 
       puts "谢谢输入成绩"
end

请输入成绩:
1124
成绩分数异常
谢谢输入成绩
请输入成绩:
99 
优秀
谢谢输入成绩

一个好的实践是,库创建一个“通用”异常类(通常是StandardError或RuntimeError的子类),并使其其他异常类从该类派生。这允许用户rescue(拯救)通用异常,从而捕获库可能引发的所有异常,即使库的未来版本添加了新的异常子类。

Exception的内置子类包括:



    NoMemoryError

    ScriptError

        LoadError

        NotImplementedError

        SyntaxError

    SecurityError

    SignalException

        Interrupt

    StandardError

        ArgumentError

            UncaughtThrowError

        EncodingError

        FiberError

        IOError

            EOFError

        IndexError

            KeyError

            StopIteration

                ClosedQueueError

        LocalJumpError

        NameError

            NoMethodError

        RangeError

            FloatDomainError

        RegexpError

        RuntimeError

            FrozenError

        SystemCallError

            Errno::*

        ThreadError

        TypeError

        ZeroDivisionError

    SystemExit

    SystemStackError

    fatal

循环

#!/usr/bin/ruby
#encoding:UTF-8
i=1
while (i<5) 
   print   i+=1
end

5.times do |i|
   print i
end
#!/usr/bin/ruby
#encoding:UTF-8
x=[1,2,3,4,5]
x.each do |i|
   puts i
end

符号与方法

  • :后跟标识符表示符号
  • 可以用.methods查看某对象的方法。参数true 表示查看超类方法,false 表示查看子类方法
#!/usr/bin/ruby
#encoding:UTF-8
sym1=:one
sym2=:two

puts sym1.to_s
sym3="three".to_sym
puts sym3
puts sym3.methods(true)
puts "=========="
puts sym3.methods(false)

  • 查看类对象定义的方法
#!/usr/bin/ruby
#encoding:UTF-8
class Test
    def test
        puts "test"
    end
end
class  Test1 < Test
    def test1
        puts "test1"
    end
end 

test1=Test1.new
test=Test.new
puts test1.class.instance_methods(false)
puts test.class.instance_methods(false)

test1
test


散列

#!/usr/bin/ruby
#encoding:UTF-8
a={:name=>"张三",:age=>35, :sex=>"男"}
b={name:"张花花","age"=>29, sex:"女"}
puts a[:name]
puts b[:name]
puts b["age"]
friend=[a,b]
friend.each do |p|
     print p[:name];puts p[:sex]
 end

张三
张花花
29
张三男
张花花女


irb(main):008:0> x=Hash.new(0)
=> {}
irb(main):009:0> x["run"]
=> 0
irb(main):010:0> x["run"]+=1
=> 1