熟悉 Ruby
我第一次接触 Ruby 的时候,基本上把它看作是“动态 C++”,因为那是我所能想到的最好的类比。当然,这需要一些调整。这篇文章讨论了一些 Ruby 特有的惯用法,这些惯用法与我所了解的概念没有直接关系,并且假设你已经使用过其他基于类的面向对象编程 (OOP) 语言,例如 C++、Java 或 Python。
我已经使用 Ruby 大约三天了,显然我已经是专家了,完全值得信赖(呵呵)。如果您发现任何错误,请指正!
非常感谢@dvik1950
Ruby练习指导轨道提供的许多帮助。
我知道这张启动画面不太适用,但它太酷了,舍不得用。你改变不了我的想法。
测试
这是一门动态语言。我是一个非常静态的人,所以单元测试几乎是避免掉头发/睡眠的首要任务。
我发现最容易上手的是minitest:
$ gem install minitest
然后,在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
取消注释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
这让我想起了在 JavaScript 中使用Mocha和Chai 。这里有一个入门指南。
%w
不要这样做:
JOES = ["average", "DiMaggio", "morning"]
执行以下操作:
JOES = %w[average DiMaggio morning]
哇!同样%i
适用于符号:
SYMS = %i[one two three]
# [:one, :two, :three]
对象.freeze
不打算改变JOES
常量?告诉 Ruby 你是认真的,然后冻结它:
JOES = %w[average DiMaggio morning].freeze
现在它实际上是不可变的!在这里阅读更多关于 Ruby 常量的内容。
字符串插值
基本上,它确实做到了。这是有效的:
def say_name(name)
output = "Hello, "
output << name
output << "!"
puts output
end
这样更好:
def say_name(name)
puts "Hello, " + name + "!"
end
但你可能想要这个:
def say_name(name)
puts "Hello, #{name}!"
end
类<<自我
要在 上重新定义方法self
,以便可以调用,您可以在 上明确MyClass.my_method
定义它:self
class MyClass
def self.my_method(str)
puts str
end
end
如果你要做很多这样的事情,你可以直接打开eigenclass或 singleton class:
class MyClass
class << self
def my_method(str)
puts str
end
end
end
我觉得这样虽然多了一些行数和缩进,但噪音确实小了一点。如果你想要更简洁,可以直接使用点运算符:
class MyClass
end
def MyClass.my_method(str)
puts str
end
这class << self
也是创建私有方法的最佳方式:
class MyClass
class << self
private
def my_private_method(str)
puts str
end
end
end
否则,你必须使用private_class_method
我认为看起来很恶心的东西:
class MyClass
private_class_method def self.my_private_method(str)
puts str
end
end
attr_accessor
您可以直接公开实例变量:
class MyClass
def initialize
@value = 0
end
def show_value
puts @value
end
end
您使用 定义构造函数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
通常最好使用以下命令同时创建两者attr_accessor
:
class MyClass
attr_accessor :value
def initialize
@value = 0
end
def show_value
puts value
end
end
您还可以分别使用attr_reader
或attr_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
执行以下操作:
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
与以前一样,重点是将数据结构的定义本地化到一个地方,以防需要再次更改。
rubocop
Rubocop是一款遵循Ruby 代码规范的 linter 。请执行以下操作:
$ gem install rubocop
然后总是这样做:
$ rubocop myFile.rb
修复所有提示的问题,如果你不明白它的意思或原因,就去查一下。学习了!
这是包含该帖子代码的repl.it :
待续...
其实有很多很酷的东西。像gsub
和 这样的方法inject
,在我最初的探索中就带来了一些惊喜。以下评论@ben
非常准确:
这里真的包罗万象。几乎涵盖了我以前用过的所有语言!找到最清晰的解决方案或最正确的应用模式有点棘手。
很久以前,我就开始接触 Ruby,那是我编程生涯的最初尝试之一。我喜欢它的简洁,而且那篇深刻的指南读起来非常有趣——如果你还没读过,即使你并非仅仅因为 Ruby 的独特性而选择它,也应该至少尝试一下。
然而,作为一名经验丰富的程序员,我对这门语言的回归感到更加开心。我认为,使用各种不同类型的语言构建的学习环境帮助我理解了如何有效地运用 Ruby。尽管 Ruby 很容易上手,但对我来说,同时学习使用 Ruby 和一般编程还是很困难的。
我个人不太推荐 Ruby 作为首选编程语言。Ruby 有这么多的范式,而且兼容性又这么好。你同意吗?
照片由 Road Trip with Raj 在 Unsplash 上拍摄
鏂囩珷鏉ユ簮锛�https://dev.to/decidously/getting-cozy-with-ruby-1l6f
Ruby 本质上是一种脚本语言。一个接一个的命令。简单到近乎残酷。
我建议打开 IRB 并输入一些命令。这实际上非常接近在环境中编码。
Ruby 有点面向对象,有点函数式,而且大多数情况下有几种方法可以完成同一件事。它有点像一个混战语言。