Ruby预览

作者: lanzhiheng | 来源:发表于2016-07-25 17:54 被阅读80次

    1. 第一个Ruby程序

    今天的第一道程序不是Hello World。而是定义一个类。

    class Greeting
      def initialize(text)
           @text = text
      end
    
      def welcome()
        @text
      end
    end
    
    # 创建一个Greeting类的实例
    my_object = Greeting.new "Hello"
    p my_object.class
    p my_object.class.instance_methods(false)
    p my_object.instance_variables
    

    上面的代码我们定义了一个类Greeting,并且创建对象,在后面运用内省的机制访问

    1. 对象所属的类。
    2. 类中含有的实例方法。
    3. 实例变量。

    打印结果如下:

    Greeting
    [:welcome]
    [:@text]
    

    跟Python的一点不同,Ruby中函数调用是可以忽略()的,而Python里面只有print语句是不需要加入(),(Python3已经修复了这个问题,必须要加上().)。-_-其实那时候我选Python2就是因为看到方法调用不需要加括号我就果断选了Python2了。

    不过考虑到可读性,建议,如果是调用带有参数的方法调用都加入括号。

    2. Ruby的各种命名简解

    Ruby中的变量定义(Learn from Perl)
    • $开头:全局变量
    • @开头:实例变量
    • @@开头:类变量, 类变量被共享在整个继承链中
    • 大写字母开头:常数

    这个规则是从Perl语言来的启发。通过特殊符号来区分不同类型的变量有助于提高程序的可读性。

    规定类名和模块名必须首字母大写

    由于在Ruby里面类名一旦定义便一般不会再修改。所以它的机制是认为命名应该是常量。否则会报错。

    # 定义小写字母开头的模块名
    ruby(main):018:0> module a
    ruby(main):019:1> end
    SyntaxError: (ruby):18: class/module name must be CONSTANT
    from /usr/bin/ruby:12:in `<main>'
    
    # 定义小写字母开头的类名
    ruby(main):020:0> class a
    ruby(main):021:1> end
    SyntaxError: (ruby):20: class/module name must be CONSTANT
    from /usr/bin/ruby:12:in `<main>'
    
    # 如果对一个常量进行赋值的话会报警告。但是还是可以修改
    ruby(main):023:0> RU = 2
    => 2
    ruby(main):024:0> RU =12
    (ruby):24: warning: already initialized constant RU
    (ruby):23: warning: previous definition of RU was here
    => 12
    
    方法名也可以带特殊符号

    Ruby 的方法命名是可以带一些特殊的符号。(这个特性据说是从Lisp学的)。
    我们最熟悉的判断一个数是奇数还是偶数:

    [9] pry(main)> a = 12
    => 12
    [10] pry(main)> a.even?
    => true
    

    由于在Ruby里面一切都是对象,所以这里的12甚至可以直接调用

    [30] pry(main)> 12.even?
    => true
    

    这里很有意思的是方法名可以加上问号,这可以用来识别一些返回true or false的方法。团队合作的时候一看,就知道这个方法是用来进行逻辑判断的。这也挺好的。不过只能放在最后面。

    这样的事情发生在Python里面就很不可思议了。Python方法名是不接受这类定义的。

    3. 链条式的调用

    Ruby是一门十分灵活的语言,又得益于它的不需要括号来调用函数的特性,我们可以写出这种代码

    [37] pry(main)> a = "heng"
    => "heng"
    [38] pry(main)> a.methods.grep /cat/
    => [:concat]
    

    这里是要查找出字符串里面的所有方法中包含关键字cat的方法名(返回的是一个数组),这里用了正则匹配。这是一个我比较喜欢的地方。 而像 a.methods.grep 顺着读,没有括号在中间的那种违和感。感觉就是在读英文。由于这种简练语法这门语言在国外有不少的爱好者。

    当然grep只是数组的内置函数

    [40] pry(main)> a.methods.class
    => Array
    [41] pry(main)> Array.instance_methods.grep /grep/
    => [:grep]
    

    所以只要返回的是对象,并且参数是可以为空的话,这条链可以很长很长。
    比如你要看字符串类型的祖先可以这样。

    [42] pry(main)> string = "I'm String"
    => "I'm String"
    
    [45] pry(main)> string.class
    => String
    [46] pry(main)> string.class.superclass
    => Object
    [47] pry(main)> string.class.superclass.superclass
    => BasicObject
    [48] pry(main)> string.class.superclass.superclass.superclass
    => nil
    

    这个BaseObject是Ruby里面最基本的类了。人们叫他白板类。它的实例方法只有很少的几个。不过在某些环境下是十分有用的。

    [12] pry(main)> BasicObject.instance_methods
    => [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__, :__binding__]
    

    如果再继续就会报错了。因为nilsuperclass会抛出异常。

    NoMethodError: undefined method `superclass' for nil:NilClass
    from (pry):52:in `__pry__'
    

    这个错误看似没用。其实会触发一些很好玩的机制。Ruby设置了不少的钩子,我们通过这些钩子可以做很多好玩的事情,这在后面介绍动态方法的时候会继续拓展。

    Happy Coding!! _

    相关文章

      网友评论

        本文标题: Ruby预览

        本文链接:https://www.haomeiwen.com/subject/imzgjttx.html