Ruby预览

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 `
'
# 定义小写字母开头的类名
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 `
'
# 如果对一个常量进行赋值的话会报警告。但是还是可以修改
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预览)