熟悉 Ruby

2025-06-11

熟悉 Ruby

我第一次接触 Ruby 的时候,基本上把它看作是“动态 C++”,因为那是我所能想到的最好的类比。当然,这需要一些调整。这篇文章讨论了一些 Ruby 特有的惯用法,这些惯用法与我所了解的概念没有直接关系,并且假设你已经使用过其他基于类的面向对象编程 (OOP) 语言,例如 C++、Java 或 Python。

我已经使用 Ruby 大约三天了,显然我已经是专家了,完全值得信赖(呵呵)。如果您发现任何错误,请指正!

非常感谢@dvik1950Ruby练习指导轨道提供的许多帮助。

我知道这张启动画面不太适用,但它太酷了,舍不得用。你改变不了我的想法。

测试

这是一门动态语言。我是一个非常静态的人,所以单元测试几乎是避免掉头发/睡眠的首要任务。

我发现最容易上手的是minitest

$ gem install minitest
Enter fullscreen mode Exit fullscreen mode

然后,在my_math_test.rb

require 'minitest/autorun'
require_relative 'my_math'

# MyMath sanity tests
class MyMathTest < Minitest::Test
  def test_times_two
    # skip
    assert_equal 8, MyMath.my_times_two(4)
  end
end
Enter fullscreen mode Exit fullscreen mode

取消注释skip即可跳过测试,避免注释/取消注释整个函数。此外,其MyMathTest < Minitest::Test语法类似于定义子类的方式,因此MyMathTest继承自Minitest::Test

还有一个更复杂的解决方案,它rspec提供了一个测试 DSL,而不是使用 Ruby 函数。测试可能如下所示:

describe MyMath do
   it "multiplies 4 by 2" do
     math = MyMath.new
     expect(math.my_times_two(4)).to eq(8)
  end
end
Enter fullscreen mode Exit fullscreen mode

这让我想起了在 JavaScript 中使用MochaChai 。这里有一个入门指南

%w

不要这样做:

JOES = ["average", "DiMaggio", "morning"]
Enter fullscreen mode Exit fullscreen mode

执行以下操作:

JOES = %w[average DiMaggio morning]
Enter fullscreen mode Exit fullscreen mode

哇!同样%i适用于符号

SYMS = %i[one two three]
# [:one, :two, :three]
Enter fullscreen mode Exit fullscreen mode

对象.freeze

不打算改变JOES常量?告诉 Ruby 你是认真的,然后冻结它:

JOES = %w[average DiMaggio morning].freeze
Enter fullscreen mode Exit fullscreen mode

现在它实际上是不可变的!在这里阅读更多关于 Ruby 常量的内容

字符串插值

基本上,它确实做到了。这是有效的:

def say_name(name)
  output = "Hello, "
  output << name
  output << "!"
  puts output
end
Enter fullscreen mode Exit fullscreen mode

这样更好:

def say_name(name)
  puts "Hello, " + name + "!"
end
Enter fullscreen mode Exit fullscreen mode

但你可能想要这个

def say_name(name)
  puts "Hello, #{name}!"
end
Enter fullscreen mode Exit fullscreen mode

类<<自我

要在 上重新定义方法self,以便可以调用,您可以在 上明确MyClass.my_method定义它:self

class MyClass
  def self.my_method(str)
    puts str
  end
end
Enter fullscreen mode Exit fullscreen mode

如果你要做很多这样的事情,你可以直接打开eigenclass或 singleton class:

class MyClass
  class << self
    def my_method(str)
      puts str
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

我觉得这样虽然多了一些行数和缩进,但噪音确实小了一点。如果你想要更简洁,可以直接使用点运算符:

class MyClass
end

def MyClass.my_method(str)
  puts str
end
Enter fullscreen mode Exit fullscreen mode

class << self也是创建私有方法的最佳方式:

class MyClass
  class << self
    private

    def my_private_method(str)
      puts str
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

否则,你必须使用private_class_method我认为看起来很恶心的东西:

class MyClass
  private_class_method def self.my_private_method(str)
    puts str
  end
end
Enter fullscreen mode Exit fullscreen mode

attr_accessor

您可以直接公开实例变量:

class MyClass
  def initialize
    @value = 0
  end
  def show_value
    puts @value
  end
end
Enter fullscreen mode Exit fullscreen mode

您使用 定义构造函数initialize()

然而,在 Ruby 中,创建 getter 和 setter 非常容易,而且通常更受欢迎。您可以手动创建:

class MyClass
  def initialize
    @value = 0
  end

  def value
    @value
  end
  def value=(new_value)
    @value = new_value
  end

  def show_value
    puts value # don't point to the `@value` var, send the `value` message
  end
end
Enter fullscreen mode Exit fullscreen mode

通常最好使用以下命令同时创建两者attr_accessor

class MyClass
  attr_accessor :value

  def initialize
    @value = 0
  end

  def show_value
    puts value
  end
end
Enter fullscreen mode Exit fullscreen mode

您还可以分别使用attr_readerattr_writer仅用于 getter 或仅用于 setter。

好处是,现在如果需要改变这个逻辑,您只需定义该方法,每个调用站点都会自动反映新的逻辑。

结构体

因为我们使用的是动态语言,所以你不必为复杂数据使用嵌套数组之类的东西。Ruby 提供了一个Struct用于结构化数据的类,它会自动为你提供这些访问器方法。

这是一个人为的例子,但不是这样的:

class MyRect
  attr_reader :rect_dims

  def initialize(arr)
    @rect_dims = arr
  end
  def show_size
    puts "Size: #{rect_dims[0]}x#{rect_dims[1]}"
  end
end
Enter fullscreen mode Exit fullscreen mode

执行以下操作:

class MyRect
  attr_reader :rect_dims
  def initialize(arr)
    @rect_dims = make_dim_struct(arr)
  end
  def show_size
    puts "Size: #{rect_dims.width}x#{rect_dims.height}"
  end

  RectDims = Struct.new(:width, :height)
  def make_dim_struct(arr)
    RectDims.new(arr[0], arr[1])
  end
end
Enter fullscreen mode Exit fullscreen mode

与以前一样,重点是将数据结构的定义本地化到一个地方,以防需要再次更改。

rubocop

Rubocop是一款遵循Ruby 代码规范的 linter 。请执行以下操作:

$ gem install rubocop
Enter fullscreen mode Exit fullscreen mode

然后总是这样做:

$ rubocop myFile.rb
Enter fullscreen mode Exit fullscreen mode

修复所有提示的问题,如果你不明白它的意思或原因,就去查一下。学习了!

这是包含该帖子代码的repl.it :

待续...

其实有很多很酷的东西。像gsub和 这样的方法inject,在我最初的探索中就带来了一些惊喜。以下评论@ben非常准确:

Ruby 本质上是一种脚本语言。一个接一个的命令。简单到近乎残酷。

我建议打开 IRB 并输入一些命令。这实际上非常接近在环境中编码。

Ruby 有点面向对象,有点函数式,而且大多数情况下有几种方法可以完成同一件事。它有点像一个混战语言。

这里真的包罗万象。几乎涵盖了我以前用过的所有语言!找到最清晰的解决方案或最正确的应用模式有点棘手。

很久以前,我就开始接触 Ruby,那是我编程生涯的最初尝试之一。我喜欢它的简洁,而且那篇深刻的指南读起来非常有趣——如果你还没读过,即使你并非仅仅因为 Ruby 的独特性而选择它,也应该至少尝试一下。

然而,作为一名经验丰富的程序员,我对这门语言的回归感到更加开心。我认为,使用各种不同类型的语言构建的学习环境帮助理解了如何有效地运用 Ruby。尽管 Ruby 很容易上手,但对我来说,同时学习使用 Ruby 和一般编程还是很困难的。

我个人不太推荐 Ruby 作为首选编程语言。Ruby 有这么多的范式,而且兼容性又这么好。你同意吗?

照片由 Road Trip with Raj 在 Unsplash 上拍摄

鏂囩珷鏉ユ簮锛�https://dev.to/decidously/getting-cozy-with-ruby-1l6f
PREV
ReactJS 与 TypeScript 的最佳实践
NEXT
全栈 JavaScript 开发人员处理日期和时间的指南