惯用的 Ruby:编写漂亮的代码

2025-05-28

惯用的 Ruby:编写漂亮的代码

Ruby 是一种优美的编程语言。

根据Ruby的官方网页,Ruby 是:

“动态的开源编程语言,注重简洁性和生产力。它语法优雅,阅读自然,易于编写。”

Ruby 的创始人是日本软件工程师松本行弘 (Yukihiro Matsumoto)。自 2011 年起,他一直担任Heroku的 Ruby 首席设计师兼软件工程师。

松本经常说,他试图让 Ruby 变得自然,而不是简单,以一种反映生活的方式。

“Ruby 外表简单,但内部却非常复杂,就像我们人体一样”——松本行弘

我对 Ruby 也有同样的感受。它是一种复杂但非常自然的编程语言,语法优美直观。

有了更直观、更快速的代码,我们就能构建更好的软件。在这篇文章中,我将向你展示如何用 Ruby 代码片段来表达我的想法(也就是代码)。

用数组方法表达我的想法

地图

使用map方法简化你的代码并得到你想要的。

方法map返回一个新数组,其中包含对枚举中的每个元素运行一次块的结果。

让我们尝试一下:

an_array.map { |element| element * element }
Enter fullscreen mode Exit fullscreen mode

就这么简单。

但是当您开始使用 Ruby 编码时,总是很容易使用each迭代器。

each迭代如下所示

user_ids = []
users.each { |user| user_ids << user.id }
Enter fullscreen mode Exit fullscreen mode

可以用一行漂亮的代码简化map :

user_ids = users.map { |user| user.id }
Enter fullscreen mode Exit fullscreen mode

或者甚至更好(更快):

user_ids = users.map(&:id)
Enter fullscreen mode Exit fullscreen mode

选择

当你习惯使用map进行编码时,有时你的代码可能是这样的:

even_numbers = [1, 2, 3, 4, 5].map { |element| element if element.even? } # [ni, 2, nil, 4, nil]
even_numbers = even_numbers.compact # [2, 4]
Enter fullscreen mode Exit fullscreen mode

nil对象也是如此。使用compact方法删除所有nil对象。

瞧,您已选择所有偶数。

任务完成。

来吧,我们可以做得更好!你听说过enumerable 模块中的select方法吗?

[1, 2, 3, 4, 5].select { |element| element.even? }
Enter fullscreen mode Exit fullscreen mode

只需一行。简单的代码。易于理解。

奖金

[1, 2, 3, 4, 5].select(&:even?)
Enter fullscreen mode Exit fullscreen mode

样本

想象一下,你需要从数组中获取一个随机元素。你刚刚开始学习 Ruby,所以你的第一个想法可能是“让我们使用random方法”,接下来会发生以下情况:

[1, 2, 3][rand(3)]
Enter fullscreen mode Exit fullscreen mode

好吧,我们可以理解这段代码,但我不确定它是否足够好。如果我们使用shuffle方法呢?

[1, 2, 3].shuffle.first
Enter fullscreen mode Exit fullscreen mode

嗯。其实我更喜欢用shuffle而不是rand。不过我发现了sample方法之后,感觉更合理了:

[1, 2, 3].sample
Enter fullscreen mode Exit fullscreen mode

真的,真的很简单。

非常自然直观。我们从数组中请求一个样本,该方法返回它。现在我很满意了。

你呢?

用 Ruby 语法表达我的想法

正如我之前提到的,我喜欢 Ruby 的编程方式。它对我来说非常自然。我将展示 Ruby 优美语法的部分内容。

隐式回报

Ruby 中的任何语句都会返回最后一个表达式的值。一个简单的例子就是 **getter** 方法。我们调用一个方法并期望返回一些值。

让我们来看看:

def get_user_ids(users)
  return users.map(&:id)
end

Enter fullscreen mode Exit fullscreen mode

但我们知道,Ruby 总是返回最后一个求值的表达式。为什么要使用return语句?

def get_user_ids(users)
  users.map(&:id)
end

Enter fullscreen mode Exit fullscreen mode

使用 Ruby 3 年后,我感觉使用几乎所有没有return语句的方法都很棒。

多项任务

Ruby 允许我同时赋值多个变量。刚开始的时候,你可能会像这样写代码:

def values
  [1, 2, 3]
end

one   = values[0]
two   = values[1]
three = values[2]
Enter fullscreen mode Exit fullscreen mode

但为什么不同时赋值多个变量呢?

def values
  [1, 2, 3]
end

one, two, three = values

Enter fullscreen mode Exit fullscreen mode

非常棒。

提出问题的方法(也称为谓词)

我在学习 Ruby 时,一个引起我注意的特性是问号(?)方法,也称为谓词方法。一开始看起来很奇怪,但现在它变得非常有意义了。你可以像这样编写代码:

movie.awesome # => true
Enter fullscreen mode Exit fullscreen mode

好吧……这没什么问题。但我们用问号:

movie.awesome? # => true
Enter fullscreen mode Exit fullscreen mode

这段代码更具表现力,我希望该方法的答案返回真值值。

我常用的方法是any?这就像询问一个数组里面是否有东西

[].any? # => false
[1, 2, 3].any? # => true

Enter fullscreen mode Exit fullscreen mode

插值

对我来说,字符串插值比字符串连接更直观。就是这样。我们来实际看看。

字符串连接的示例:

programming_language = "Ruby"
programming_language + " is a beautiful programming_language" # => "Ruby is a beautiful programming_language"
Enter fullscreen mode Exit fullscreen mode

字符串插值的示例:

programming_language = "Ruby"
"#{programming_language} is a beautiful programming_language" # => "Ruby is a beautiful programming_language"
Enter fullscreen mode Exit fullscreen mode

我更喜欢字符串插值。

你怎么认为?

if 语句

我喜欢使用if语句:

def hey_ho?
  true
end

puts "let’s go" if hey_ho?
Enter fullscreen mode Exit fullscreen mode

像这样编写代码真是太好了。

感觉非常自然。

try 方法(Rails 模式开启)

try方法会调用由符号标识的方法,并向其传递任意参数和/或指定的代码块。这类似于 Ruby 的Object#send 方法。与该方法不同的是,如果接收对象是nil对象或NilClass,则返回nil

使用if 和 unless条件语句:

user.id unless user.nil?
Enter fullscreen mode Exit fullscreen mode

使用**try**方法:

user.try(:id)
Enter fullscreen mode Exit fullscreen mode

从 Ruby 2.3 开始,我们可以使用 Ruby 的安全导航运算符** (&.)** 代替 Rails 的 **try ** 方法。

user&.id
Enter fullscreen mode Exit fullscreen mode

双管道等于 (||=) / 记忆

这个功能太酷了。就像把值缓存在变量里一样。

some_variable ||= 10
puts some_variable # => 10

some_variable ||= 99
puts some_variable # => 10

Enter fullscreen mode Exit fullscreen mode

你根本不需要使用if语句。只需使用双竖线等于号(||=)即可。

簡單又容易。

类静态方法

我喜欢编写 Ruby 类的一种方法是定义一个**静态**方法(类方法)。

GetSearchResult.call(params)
Enter fullscreen mode Exit fullscreen mode

简单。美观。直观。

后台发生了什么?

class GetSearchResult
  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # ... your code here ...
  end
end

Enter fullscreen mode Exit fullscreen mode

self.call方法初始化一个实例,该对象调用 **call ** 方法。Interactor设计模式使用它。

Getter 和 Setter

对于相同的GetSearchResult类,如果我们想使用参数,我们可以使用 @params

class GetSearchResult
  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # ... your code here ...
    @params # do something with @params
  end
end

Enter fullscreen mode Exit fullscreen mode

我们定义一个setter **和 **getter:

class GetSearchResult
  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # ... your code here ...
    params # do something with params method here
  end

  private

  def params
    @params
  end

  def params=(parameters)
    @params = parameters
  end
end

Enter fullscreen mode Exit fullscreen mode

或者我们可以定义attr_readerattr_writerattr_accessor

class GetSearchResult
  attr_reader :param

  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # ... your code here ...
    params # do something with params method here
  end
end

Enter fullscreen mode Exit fullscreen mode

好的。

我们不需要定义gettersetter方法。代码变得更简单了,这正是我们想要的。

轻敲

假设你要定义一个create_user方法。此方法将实例化、设置参数、保存并返回用户。

我们开始做吧。

def create_user(params)
  user       = User.new
  user.id    = params[:id]
  user.name  = params[:name]
  user.email = params[:email]
  # ...
  user.save
  user
end
Enter fullscreen mode Exit fullscreen mode

很简单。没什么问题。

现在让我们用tap方法来实现它

def create_user(params)
  User.new.tap do |user|
    user.id    = params[:id]
    user.name  = params[:name]
    user.email = params[:email]
    # ...
    user.save
  end
end
Enter fullscreen mode Exit fullscreen mode

您只需要担心用户参数,tap方法将为您返回用户对象。

就是这样

我们学会了如何使用 Ruby 语言进行编码来编写惯用的 Ruby

  • 数组方法

  • 句法

我们还了解到 Ruby 是多么的美观和直观,而且运行速度更快。

就这样吧,伙计们!我会更新我的博客,并添加更多细节。我的想法是分享精彩内容,也希望社区能帮助改进这篇文章!☺

我希望你们喜欢这些内容并学会如何编写漂亮的代码(和更好的软件)。

如果你想要完整的 Ruby 课程,学习实际的编程技能并构建项目,那就试试“一个月 Ruby 训练营”吧。到时候见☺

这篇文章最初出现在我的Renaissance Developer 出版物

玩得开心,继续学习,并始终坚持编码!

MediumTwitterGithubLinkedIn。☺

文章来源:https://dev.to/teekay/idiomatic-ruby-writing-beautiful-code-56ef
PREV
使用 webP 图像可以更快地加载网页
NEXT
我作为一名软件工程师如何在两年内获得四次加薪