工作需要,需要使用静态语言crystal,但crystal的资料很少,语法接近ruby,网上说crystal是一帮ruby的爱好者搞起来的语言,废话不多,进入主题。
学习视频:https://www.bilibili.com/video/BV1QW411F7rh?p=1
ruby 通过 -v 查看版本 Python -V
[sidian@VM_0_17_centos ruby_study]$ ruby -v ruby 2.0.0p648 (2015-12-16) [x86_64-linux] [sidian@VM_0_17_centos ruby_study]$ python3 -V Python 3.7.4 [sidian@VM_0_17_centos ruby_study]$
通过irb进入交互界面. Python 进行命令行python就可以,或者安装了ipython命令行ipython进入交互模式
通过puts 屏幕终端输出信息 py通过print输出屏幕终端
[sidian@VM_0_17_centos ruby_study]$ irb irb(main):001:0> puts "hello world" hello world => nil irb(main):002:0> exit [sidian@VM_0_17_centos ruby_study]$ python3 Python 3.7.4 (default, Oct 28 2019, 00:18:00) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> print("hello,owlrd") hello,owlrd >>>
ruby构建函数基本与Python差不多
[sidian@VM_0_17_centos ruby_study]$ cat hello.rb #!/usr/bin/ruby -w def sayhello(name="sidian") puts "hello #{name}." end #sayhello("sidian") sayhello("wudian")
总体来说就多了一个end,而且当默认没有参数的时候,可以省略小括号。
接下来直接定义类,跟Python非常像
[sidian@VM_0_17_centos ruby_study]$ cat class_player.rb class Player def initialize(name = "sidian") @name = name end def show() puts "play: #{@name}" end end sidian = Player.new("wudian") sidian.show() world = Player.new("world") world.show()
从定义可以看出,实例化需要使用类属性new()执行,调用该类属性。通过new小括号里面进行实例化参数的传递
类内部实例的属性定义,通过@号实现,这个跟Python中的self.的形式进行实例属性复制差不多。
当调用类属性new以后,首先自动触发执行类方法initialize函数,进行实例对象的初始化并返回。相对与Python的__init__初始化方法弱爆了。
格式话输出的还是通过#{}的方式输出。
ruby的instance_methods, respond_to?, send的三个命令参数,对应Python的dir或vars,第二个就是hasattr,第三个就是getattr()以后执行.
首先展示instance_methods这是一个类属性,实例不具有,通过类名可以调用该方法,内部可以传参数(true或false)【暂时没有找到查看所有实例属性的函数或者方法】
class Game def initialize(title = "学习", price = "无价") @title = title @price = price # 实例属性复制 end def show puts "标题是:#{@title}" puts "价格是:#{@price}" end def show2() end def show3 end end puts Game.instance_methods(false) g = Game.new() puts g puts Game.instance_methods(true) puts g.instance_methods(false) ~
结果
ruby class_game show show2 show3 #<Game:0x00000000f9ac90> show show2 show3 nil? === =~ !~ eql? hash <=> class singleton_class clone dup taint tainted? untaint untrust untrusted? trust freeze frozen? to_s inspect methods singleton_methods protected_methods private_methods public_methods instance_variables instance_variable_get instance_variable_set instance_variable_defined? remove_instance_variable instance_of? kind_of? is_a? tap send public_send respond_to? extend display method public_method define_singleton_method object_id to_enum enum_for == equal? ! != instance_eval instance_exec __send__ __id__ class_game:20:in `<main>': undefined method `instance_methods' for #<Game:0x00000000f9ac90 @title="学习", @price="无价"> (NoMethodError) [sidian@VM_0_17_centos ruby_study]$
通过结果可以看出来instance_methods类方法,实例使用会报错,如果传入flase返回的是定义类的时候传入的属性(函数),
如果传入true或者不传入,那返回的是类所有的属性,一些属性应该是类创建的时候,继承与python中的object类似。
16 puts Game.instance_methods(false) 17 g = Game.new() 18 puts g 19 if g.respond_to?("shw2") # 这个就跟Python中的hasattr就一样的,只不过一个是函数,一个是方法 20 puts "show2 is in" 21 end 22 23 # puts Game.instance_methods() 24 # puts g.instance_methods(false)
resopnt_to?返回一个实例对象是否存在一个继承与类的属性???应该是,至少实例的属性不行,这个跟hasattr有点区别。
我刚测试,只有show,show1,show2返回的是真,实例的属性resopt_to并不会读取到。根据我的测试返回的就是instance_methods()类方法调用以后返回值里面的值,只要
在该值范围的内的都为真。
send就跟getattr()()这个有点像了,就是通过字符串的形式给实例传递方法的名字,并运行该方法。ruby的函数,没有默认参数的情况下,不用()也会执行
17 g = Game.new() 18 puts g 19 if g.respond_to?("send") # "send"在instance_methods的内容中,所以会执行g.send 20 puts g.send("show") # 传入类中定义的函数 21 end 22 23 # puts Game.instance_methods() 24 # puts g.instance_methods(false)
结果
[sidian@VM_0_17_centos ruby_study]$ ruby class_game show show2 show3 #<Game:0x00000001446c08> 标题是:学习 价格是:无价