• Java转Ruby【快速入门】


    最近参加实习了,公司的技术栈中需要用到 Ruby 以及 Rails 框架,所以算是开始了踩坑之旅吧..

    Ruby 简介

    网上的简介要搜都能搜到,具体涉及的包括历史啦之类这里不再赘述,提几个关键词吧:

    • 1993 年由日本的松本行弘创建
    • 纯粹面相对象编程/ 脚本语言/ 解释型/ 动态类型

    对于准备迈入 Ruby 的 Java 程序员来说,有几个地方需要特别的去了解一下。

    • 纯粹面相对象
      其实经过论证,Java 同 Ruby 一样都是纯粹的面相对象的语言,这也就意味着包含所有的数字等在内都是对象,注意所有的都是。
    • 脚本语言
      这意味着你写的程序不用编译就能运行,甚至实时生效。
    • 解释型
      同 Java 一样,Ruby 有自己的虚拟机,运行需要一定的环境,也就是 Ruby 解释器,它会负责把 Ruby 翻译成及其能够执行的代码。
    • 动态类型
      Ruby 中的数据更像是一种符号,在使用的时候不检查类型,而是在运行时动态的检查。

    为什么是 Ruby ?

    • 原因很简单:高效/ 灵活/ 优雅/ 简单

    如果你再稍微花一些心思搜索一下 Ruby on Rails 这个 Web 开发框架,并且打开一些详细说明了体验之后的文章或者是多年经验开发者的分享,你可能会对它产生一些兴趣,这一Part就留着之后介绍了,这也是为以后学习 RoR 框架做准备的。

    总之我们要明确我们目的:知道最基本的语法,理解其中的一些关键概念即可。

    Ruby 初体验

    Mac OX 中有默认的 Ruby 环境,我们可以来一个最短的 "Hello World" 程序,首先在控制台中输入 irb 命令,然后输入 puts "Hello World!" 命令:

    irb
    irb(main):001:0> puts "Hello World!"
    Hello World!
    => nil
    

    你就能看到紧跟着你的输入会有一个 Hello World! 的输出以及一个 nil (对应 Java 中的 null)的返回。

    再来一个更加复杂的例子,我们这一次来创建一个数组然后循环输出它:

    irb(main):002:0> properties = ['name','age','sex']
    => ["name", "age", "sex"]
    irb(main):003:0> properties
    => ["name", "age", "sex"]
    irb(main):005:0> properties.each {|property| puts "This is #{property}."}
    This is name.
    This is age.
    This is sex.
    => ["name", "age", "sex"]
    

    不知道感觉如何?至少我们可以直观的感受到:

    • 不用生命变量,直接 = 就好
    • 每条 Ruby 代码都会返回某个值

    从 Java 到 Ruby

    Java 非常成熟,并且通过 Spring 的加持得到了许多企业的青睐,但是不知道大家有没有感受到一点:它或许有些啰嗦...(我乱说的啊,我也不知道,别问我啊..)从 Java 到 Ruby 据说可以预见性的将代码的规模量大大缩小,因此也能使用更少的时间来输出产品原型。

    相似点

    Ruby 与 Java 有一些相似的地方...

    • 垃圾回收器帮你管理内存。
    • 强类型对象。
    • 有 public、 private 和 protected 方法。
    • 拥有嵌入式文档工具(Ruby 的工具叫 rdoc)。rdoc 生成的文档与 javadoc 非常相似。

    不同点

    Ruby 与 Java 不同的地方...

    • 你不需要编译你的代码。你只需要直接运行它。
    • 有几个不同的流行的第三方GUI工具包。Ruby 用户可以尝试 WxRuby、 FXRuby、 Ruby-GNOME2、 Qt 或 Ruby 内置的 Tk。
    • 定义像类这样的东西时,可以使用 end 关键字,而不使用花括号包裹代码块。
    • 使用 require 代替 import
    • 所有成员变量为私有。在外部,使用方法获取所有你需要的一切。
    • 方法调用的括号通常是可选的,经常被省略。
    • 一切皆对象,包括像 2 和 3.14159 这样的数字。
    • 没有静态类型检查。
    • 变量名只是标签。它们没有相应的类型。
    • 没有类型声明。按需分配变量名,及时可用(如:a = [1,2,3] 而不是 int[] a = {1,2,3};)。
    • 没有显式转换。只需要调用方法。代码运行之前,单元测试应该告诉你出现异常。
    • 使用 foo = Foo.new("hi") 创建新对象,而非 Foo foo = new Foo("hi")
    • 构造器总是命名为“initialize” 而不是类名称。
    • 作为接口的替代,你将获得“混入(mixins)”。
    • 相比 XML,倾向于使用 YAML。
    • nil 替代 null
    • Ruby 对 == 和 equals() 的处理方式与 Java 不一样。测试相等性使用 ==(Java 中是 equals())。测试是否为同一对象使用 equals?()(Java 中是 ==)。

    以上的相同与不同来自:https://www.ruby-lang.org/zh_cn/documentation/ruby-from-other-languages/to-ruby-from-java/
    延伸阅读:https://gquintana.github.io/2017/01/08/From-Java-to-Ruby.html


    Ruby 基础

    在大致了解了 Ruby 一些基础信息之后,我们开始 Ruby 基础语法的学习,虽然面对一门新的语言,语法啊特性啊之类的了解很有必要,但还是想在了解之前看一看 Ruby 的一些代码规范,好让自己能快速了解 Ruby 的基础上还能养成一个良好的编码习惯。

    学习之前必备 - 代码规范

    或许有些语句还不能理解,没关系,有一个基础印象就好。

    • 一般来讲,Ruby 中的变量名和方法名使用下划线命名法(小写字母 + _),类名和模块名使用 Java 类似的驼峰命名法

    • 每个缩进级别使用两个 space(又名软 tabs),不要使用硬 tabs

    # bad - four spaces
    def some_method
        do_something
    end
    
    # good
    def some_method
      do_something
    end
    
    • 不用使用 ; 来分割语句和表达式。以此推论 - 一行使用一个表达式
    # bad
    puts 'foobar'; # superfluous semicolon
    
    puts 'foo'; puts 'bar' # two expression on the same line
    
    # good
    puts 'foobar'
    
    puts 'foo'
    puts 'bar'
    
    puts 'foo', 'bar' # this applies to puts in particular
    
    • 避免单行方法。即便还是会受到一些人的欢迎,这里还是会有一些古怪的语法用起来很容易犯错. 无论如何 - 应该一行不超过一个单行方法.
    # bad
    def too_much; something; something_else; end
    
    # okish - notice that the first ; is required
    def no_braces_method; body end
    
    # okish - notice that the second ; is optional
    def no_braces_method; body; end
    
    # okish - valid syntax, but no ; make it kind of hard to read
    def some_method() body end
    
    # good
    def some_method
      body
    end
    

    空方法是这个规则的例外。

    # good
    def no_op; end
    
    • 当赋值一个条件表达式的结果给一个变量时,保持分支的缩排在同一层。
    # bad - pretty convoluted
    kind = case year
    when 1850..1889 then 'Blues'
    when 1890..1909 then 'Ragtime'
    when 1910..1929 then 'New Orleans Jazz'
    when 1930..1939 then 'Swing'
    when 1940..1950 then 'Bebop'
    else 'Jazz'
    end
    
    result = if some_cond
      calc_something
    else
      calc_something_else
    end
    
    # good - it's apparent what's going on
    kind = case year
           when 1850..1889 then 'Blues'
           when 1890..1909 then 'Ragtime'
           when 1910..1929 then 'New Orleans Jazz'
           when 1930..1939 then 'Swing'
           when 1940..1950 then 'Bebop'
           else 'Jazz'
           end
    
    result = if some_cond
               calc_something
             else
               calc_something_else
             end
    
    # good (and a bit more width efficient)
    kind =
      case year
      when 1850..1889 then 'Blues'
      when 1890..1909 then 'Ragtime'
      when 1910..1929 then 'New Orleans Jazz'
      when 1930..1939 then 'Swing'
      when 1940..1950 then 'Bebop'
      else 'Jazz'
      end
    
    result =
      if some_cond
        calc_something
      else
        calc_something_else
      end
    
    • 在方法定义之间使用空行并且一个方法根据逻辑段来隔开。
    def some_method
      data = initialize(options)
    
      data.manipulate!
    
      data.result
    end
    
    def some_methods
      result
    end
    
    • 不要使用区块注释。它们不能由空白引导(=begin 必须顶头开始),并且不如普通注释容易辨认。
    # bad
    == begin
    comment line
    another comment line
    == end
    
    # good
    # comment line
    # another comment line
    
    • 使用括号将def的参数括起来。当方法不接收任何参数的时候忽略括号。
    # bad
    def some_method()
      # body omitted
    end
    
    # good
    def some_method
      # body omitted
    end
    
    # bad
    def some_method_with_arguments arg1, arg2
      # body omitted
    end
    
    # good
    def some_method_with_arguments(arg1, arg2)
      # body omitted
    end
    
    • 从来不要使用 for, 除非你知道使用它的准确原因。大多数时候迭代器都可以用来替 forfor 是由一组 each 实现的 (因此你正间接添加了一级),但是有一个小道道 - for 并不包含一个新的 scope (不像 each)并且在它的块中定义的变量在外面也是可以访问的。(这里有些像 Java 中不用 for-each 语句类似,感兴趣的也可以去搜一搜)
    arr = [1, 2, 3]
    
    # bad
    for elem in arr do
      puts elem
    end
    
    # note that elem is accessible outside of the for loop
    elem #=> 3
    
    # good
    arr.each { |elem| puts elem }
    
    # elem is not accessible outside each's block
    elem #=> NameError: undefined local variable or method `elem'
    
    • 利用 if and case 是表达式这样的事实它们返回一个结果。
    # bad
    if condition
      result = x
    else
      result = y
    end
    
    # good
    result =
      if condition
        x
      else
        y
      end
    
    • 布尔表达式使用&&/||, and/or用于控制流程。(经验Rule:如果你必须使用额外的括号(表达逻辑),那么你正在使用错误的的操作符。)
    # boolean expression
    if some_condition && some_other_condition
      do_something
    end
    
    # control flow
    document.save? or document.save!
    
    • 永远不要使用 unlesselse 组合。将它们改写成肯定条件。
    # bad
    unless success?
      puts 'failure'
    else
      puts 'success'
    end
    
    # good
    if success?
      puts 'success'
    else
      puts 'failure'
    end
    
    • 不用使用括号包含 if/unless/while 的条件。
    # bad
    if (x > 10)
      # body omitted
    end
    
    # good
    if x > 10
      # body omitted
    end
    
    • 倾向使用 module,而不是只有类方法的 class。类别应该只在创建实例是合理的时候使用。
    # bad
    class SomeClass
      def self.some_method
        # body omitted
      end
    
      def self.some_other_method
      end
    end
    
    # good
    module SomeClass
      module_function
    
      def some_method
        # body omitted
      end
    
      def some_other_method
      end
    end
    
    • 当你希望将模块的实例方法变成 class 方法时,偏爱使用 module_function 胜过 extend self
    module Utilities
      extend self
    
      def parse_something(string)
        # do stuff here
      end
    
      def other_utility_method(number, string)
        # do some more stuff
      end
    end
    
    # good
    module Utilities
      module_function
    
      def parse_something(string)
        # do stuff here
      end
    
      def other_utility_method(number, string)
        # do some more stuff
      end
    end
    
    • 总是为你自己的类提供 to_s 方法, 用来表现这个类(实例)对象包含的对象.
    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      def to_s
        "#@first_name #@last_name"
      end
    end
    
    • 考虑使用 Struct.new, 它可以定义一些琐碎的 accessors, constructor(构造函数) 和 comparison(比较) 操作。
    # good
    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    end
    
    # better
    class Person < Struct.new(:first_name, :last_name)
    end
    
    • 考虑使用 Struct.new,它替你定义了那些琐碎的存取器(accessors),构造器(constructor)以及比较操作符(comparison operators)。
    # good
    class Person
      attr_accessor :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    end
    
    # better
    Person = Struct.new(:first_name, :last_name) do
    end
    
    • 不要去 extend 一个 Struct.new - 它已经是一个新的 class。扩展它会产生一个多余的 class 层级 并且可能会产生怪异的错误如果文件被加载多次。

    • 鸭子类型(duck-typing)优于继承。

    # bad
    class Animal
      # abstract method
      def speak
      end
    end
    
    # extend superclass
    class Duck < Animal
      def speak
        puts 'Quack! Quack'
      end
    end
    
    # extend superclass
    class Dog < Animal
      def speak
        puts 'Bau! Bau!'
      end
    end
    
    # good
    class Duck
      def speak
        puts 'Quack! Quack'
      end
    end
    
    class Dog
      def speak
        puts 'Bau! Bau!'
      end
    end
    
    • 当访问一个数组的第一个或者最后一个元素,倾向使用 first 或 last 而不是 [0] 或 [-1]。

    • 优先使用 字符串插值 来代替 字符串串联

    # bad
    email_with_name = user.name + ' <' + user.email + '>'
    
    # good
    email_with_name = "#{user.name} <#{user.email}>"
    
    # good
    email_with_name = format('%s <%s>', user.name, user.email)
    
    • 在对象插值的时候不要使用 Object#to_s,它将会被自动调用。

    • 操作较大的字符串时, 避免使用 String#+ 做为替代使用 String#<<。就地级联字符串块总是比 String#+ 更快,它创建了多个字符串对象。

    # good and also fast
    html = ''
    html << '<h1>Page title</h1>'
    
    paragraphs.each do |paragraph|
      html << "<p>#{paragraph}</p>"
    end
    
    • RuboCop
      RuboCop 是一个基于本指南的 Ruby 代码风格检查工具。 RuboCop 涵盖了本指南相当大的部分,支持 MRI 1.9 和 MRI 2.0,而且与 Emacs 整合良好。

    • RubyMine
      RubyMine 的代码检查是 部分基于 本指南的。

    基于下面链接简化了大部分,因为有一些编码风格能从 Java 自然的切换过来,而且我们也可以使用相应的工具来检查我们的代码,更多可以看这里:https://ruby-china.org/wiki/coding-style

    Ruby 语言基础

    其实通过上面的语法规范,我们或多或少能感知到一些 Ruby 的语法,有一些细节的地方可以自行去菜鸟教程or其他网站能看到,下面我们就着一些重要的东西快速的学习一遍吧..

    数据类型

    Ruby 中有以下几种不同的数据类型:

    • 数字/ 字符串/ 符号/ 哈希/ 数组/ 布尔
      比较在意的是 Ruby 并没有 Java 中的枚举类型,可能是出于安全方面的考虑吧..(我也不知道...)

    • 符号就像字符串。一个符号之前是冒号(:)。例如:

    :abcd
    

    它们不包含空格。 含有多个单词的符号用(_)写成。 字符串和符号之间的一个区别是,如果文本是一个数据,那么它是一个字符串,但如果它是一个代码,它是一个符号。

    符号是唯一的标识符,表示静态值,而字符串表示更改的值。

    示例:

    irb(main):011:0> "string".object_id
    => 26922000
    irb(main):012:0> "string".object_id
    => 29115220
    irb(main):013:0> :symbol.object_id
    => 788188
    irb(main):014:0> :symbol.object_id
    => 788188
    
    • 哈希将其值分配给其键。 它们可以用键关联指定值。键的值由 => 符号分配。 键/值对之间用逗号分隔,所有对都用大括号括起来。 例如:
    {"key1" => "value1", "key2" => "Chemistry", "key3" => "Maths"}
    

    示例:

    data = {"key1" => "Physics", "key2" => "Chemistry", "key3" => "Maths"}   
    puts data["key1"]   
    puts data["key2"]   
    puts data["key3"]
    

    执行上述代码,得到以下结果:

    Physics
    Chemistry
    Maths
    

    变量

    Ruby 有四种类型的变量,变量的命名方式决定了变量的种类

    • 局部变量
      以英文小写字母或者 _ 开头,作用域等同于 Java 局部变量。

    • 全局变量
      $ 开头,作用域等同于 Java 全局变量。只要全局变量的名称相同,不管变量在程序的哪个部分使用,程序都认为是它们是同一个变量。未初始化的全局变量的值会被初始化为:nil。建议不要使用全局变量,因为它们使程序变得秘密和复杂。

    示例:

    $global_var = "GLOBAL"   
    class One   
      def display   
         puts "Global variable in One is #$global_var"   
      end   
    end   
    class Two   
      def display   
         puts "Global variable in Two is #$global_var"   
      end   
    end   
    
    oneobj = One.new   
    oneobj.display   
    twoobj = Two.new   
    twoobj.display
    

    执行代码输出结果如下:

    Total number of states written: 4
    Total number of states written: 4
    Total number of states written: 4
    Total number of states written: 4
    
    • 实例变量
      @ 开头,在同一个实例中,程序可以超越方法定义,任意引用、修改实例变量。它属于类的一个实例,可以从方法中的类的任何实例访问。 它们只能访问一个特定的类的实例。它们不需要初始化,未初始化的实例变量的值是:nil

    示例:

    class States   
       def initialize(name)   
          @states_name=name   
       end   
       def display()   
          puts "States name #@states_name"   
        end   
    end   
    
    # Create Objects   
    first=States.new("Hainan")   
    second=States.new("GuangDong")   
    third=States.new("Beijing")   
    fourth=States.new("ShangDong")   
    
    # Call Methods   
    first.display()   
    second.display()   
    third.display()   
    fourth.display()
    

    执行代码输出结果如下:

    States name GuangDong
    States name Beijing
    States name ShangDong
    
    • 类变量
      @@ 开头,作用域为该类的所有实例。需要在使用前进行初始化,由类的所有后代共享,未初始化的变量将导致错误。

    示例:

    class States   
       @@no_of_states=0   
       def initialize(name)   
          @states_name=name   
          @@no_of_states += 1   
       end   
       def display()   
         puts "State name #@state_name"   
        end   
        def total_no_of_states()   
           puts "Total number of states written: #@@no_of_states"   
        end   
    end   
    
    # Create Objects   
    first=States.new("Assam")   
    second=States.new("Meghalaya")   
    third=States.new("Maharashtra")   
    fourth=States.new("Pondicherry")   
    
    # Call Methods   
    first.total_no_of_states()   
    second.total_no_of_states()   
    third.total_no_of_states()   
    fourth.total_no_of_states()
    

    执行上面代码输出结果如下:

    Total number of states written: 4
    Total number of states written: 4
    Total number of states written: 4
    Total number of states written: 4
    

    类和对象

    Object 类是所有 Ruby 对象的默认根。 Ruby 对象继承自 BasicObject(它是Ruby中所有类的父类)类,允许创建替代对象层次结构。

    首先与 Java 很不同的是创建对象:

    Object newObject = new Object(); // Java 中新建对象
    

    对比 Ruby:

    objectName = className.new
    

    每个 Ruby 类都是 Class 类的一个实例。通常对于类名,使用驼峰命名规则,类的名称始终以大写字母开头。定义类是用 end 关键字完成的。

    语法

    class ClassName  
        codes...  
    end
    

    我们使用上面学习过的语法规范来创建一个 Person 类(写上 to_s 方法):

    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      def to_s
        "#@first_name #@last_name"
      end
    end
    

    注意这里的 attr_reader 对应在 Java 中相当于为 first_namelast_name 定义了 getter ,在 Ruby 中,从对象外部不能直接访问实例变量或对实例变量赋值,需要通过方法来访问对象的内部,如果像 Java 那样一遍一遍为每一个变量写 getter/setter 就有些冗杂了,Ruby 为我们提供了一些方便的存取器。

    定义 意义
    attr_reader :name 只读(定义 name 方法)
    attr_writer :name 只写(定义 name= 方法)
    attr_accessor :name 读写(定义以上两个方法)

    另外一点上面有一个非常有趣的规范是使用 Struct.new 来简化代码,我觉得很酷也想把它应用在上述 Person 类的创建中,但是发现失败了(不能在其中定义其他功能性的代码),所以可能结论是:这样的简化只适用于一些实体类保存数据的类吧。

    方法

    Ruby 方法使用 def 关键字开始,最后还需要使用 end 关键字来表示方法定义结束。

    语法:

    def methodName  
        code...  
    end
    

    示例:

    def method_defining(a1 = "Ruby", a2 = "Python")
       puts "The programming language is #{a1}"
       puts "The programming language is #{a2}"
    end
    method_defining "C", "C++"
    method_defining
    

    运行上面的代码执行结果如下:

    The programming language is C
    The programming language is C++
    The programming language is Ruby
    The programming language is Python
    

    方法返回值:

    在初探 Ruby 的时候我们就感受到,貌似每一条指令都会返回一个返回值,方法也是这样,在 Ruby 中每个方法都有一个返回值,这个返回的值将是最后一个语句的值。例如:

    def my_method
       i = 100
       j = 10
       k = 1
    end
    

    上面代码中,最后方法的返回值是 1

    Ruby return 语句

    Ruby 中的 return 语句用于从 Ruby 方法中返回一个或多个值

    示例:

    def method
       i = 100
       j = 200
       k = 300
    return i, j, k
    end
    var = method
    puts var
    

    上面代码结果如下:

    100
    200
    300
    

    可变参数:

    假设声明一个方法需要两个参数,每当调用这个方法时,需要传递两个参数。但是,Ruby允许您声明使用可变数量参数的方法。 让我们来看一下这个示例:

    def sample (*test)
       puts "The number of parameters is #{test.length}"
       for i in 0...test.length
          puts "The parameters are #{test[i]}"
       end
    end
    sample "Maxsu", "6", "F"
    sample "Mac", "38", "M", "MCA"
    

    执行上面代码,得到如下结果:

    The number of parameters is 3
    The parameters are Maxsu
    The parameters are 6
    The parameters are F
    The number of parameters is 4
    The parameters are Mac
    The parameters are 38
    The parameters are M
    The parameters are MCA
    

    类方法:

    当方法在类定义之外定义时,默认情况下该方法被标记为 private。 另一方面,默认情况下,类定义中定义的方法被标记为 public。模块的默认可见性和 private 标记可以通过模块的 publicprivate 更改。

    Ruby 给出一种不用实例化一个类就可以访问一个方法。下面来看看看如何声明和访问类方法 -

    class Accounts
       def reading_charge
       end
       def Accounts.return_date
       end
    end
    

    访问类方法 -

    Accounts.return_date
    

    模板

    Ruby 模块是方法和常量的集合。暂时你可简单的理解为一个不能实例化的类,这样做的好处是一来可以提供一个命名空间避免名字冲突,另一个是实现了 mixin 的功能。

    不知道您有没有发现,Ruby 没有提供多重继承的功能,但 Ruby 的模板几乎消除了多重继承的需要,提供了一种名为 mixin 的装置。

    示例:

    module A
      def a1
      end
      def a2
      end
    end
    module B
      def b1
      end
      def b2
      end
    end
    
    class Sample
      include A
      include B
      def s1
      end
    end
    
    samp=Sample.new
    samp.a1
    samp.a2
    samp.b1
    samp.b2
    samp.s1
    

    Ruby 代码在其他编程语言中被称为闭包。它由一组代码组成,它们始终用大括号括起来,或者在 do..end 之间书写。大括号语法总是具有比 do..end 语法更高的优先级。也就是说大括号优先级高,do..end 优先级低。

    语法:

    block_name{
       statement1
       statement2
       ..........
    }
    

    yield语句:

    def test
       puts "在 test 方法内"
       yield
       puts "你又回到了 test 方法内"
       yield
    end
    test {puts "你在块内"}
    

    上面代码运行结果如下:

    在 test 方法内
    你在块内
    你又回到了 test 方法内
    你在块内
    

    块和方法:

    def test
      yield
    end
    test{ puts "Hello world"}
    

    本实例是实现块的最简单的方式。您使用 yield 语句调用 test 块。

    但是如果方法的最后一个参数前带有 &,那么您可以向该方法传递一个块,且这个块可被赋给最后一个参数。如果 *& 同时出现在参数列表中,& 应放在后面。

    def test(&block)
       block.call
    end
    test { puts "Hello World!"}
    

    上述代码运行结果如下:

    Hello World!
    

    这一部分建议再去看一下慕课网上的教程,看关于第三章的内容即可:Ruby语言快速入门:https://www.imooc.com/learn/765


    总结

    经过以上简单的学习,我们对 Ruby 有了一个大致的了解,算是简单入了个门(有一些简单的例如循环啊,判断啊,运算符之类的简单我就没有写了),更多的东西需要自己平时的编码中去总结学习(肯定有一些坑需要自己去填的)。

    参考文章:
    1.Ruby 教程 - 菜鸟驿站 - http://www.runoob.com/ruby/ruby-intro.html
    2.Ruby 教程 - 易百教程 - https://www.yiibai.com/ruby
    3.20分钟体验 Ruby - https://www.ruby-lang.org/zh_cn/documentation/quickstart/
    4.笨方法学 Ruby - https://lrthw.github.io/intro/
    5.Ruby 快速入门 - https://wdxtub.com/2016/03/30/ruby-first-step/


    按照惯例黏一个尾巴:

    欢迎转载,转载请注明出处!
    简书ID:@我没有三颗心脏
    github:wmyskxz
    欢迎关注公众微信号:wmyskxz
    分享自己的学习 & 学习资料 & 生活
    想要交流的朋友也可以加qq群:3382693

  • 相关阅读:
    【NOIP】提高组2015 运输计划
    【BZOJ】1635: [Usaco2007 Jan]Tallest Cow 最高的牛
    【51nod】1766 树上的最远点对
    【BZOJ】2054: 疯狂的馒头
    【SRM20】数学场
    【Luogu】P3930 SAC E#1
    【Luogu】P3927 SAC E#1
    【Luogu】 P3928 SAC E#1
    【Codeforces】868C. Qualification Rounds
    【CodeForces】866D. Buy Low Sell High
  • 原文地址:https://www.cnblogs.com/wmyskxz/p/10772690.html
Copyright © 2020-2023  润新知