您是否避免使用任何Ruby语言功能?

时间:2009-06-04 09:50:31

标签: ruby syntax

在我看来,Ruby具有很多语法灵活性,很多东西可能以多种方式编写。

为了清晰起见,是否有任何语言特性/语法糖/编码约定避免作为Ruby程序员?我问你选择不是故意使用的东西,而不是你还需要学习的东西。

如果您的回答是“我使用了所有内容!”,您是否曾评论过如果读者知道相关Ruby语法会显而易见的代码?

[我对RoR环境中的Ruby特别感兴趣,但欢迎一切。]

8 个答案:

答案 0 :(得分:11)

整个范围的“$”全局变量(参见Pickaxe2 pp333-336)大部分都是从Perl继承的,虽然我偶尔会发现自己使用$:而不是$ LOAD_PATH。 / p>

答案 1 :(得分:8)

我通常不会过度使用monkey patching因为它可能会导致一些可维护性和可读性问题。如果使用得当,它是一个很棒的功能,但它很容易被带走。

答案 2 :(得分:7)

for ... in ...循环。它直接编译为obj.each(并相应地抛出一个奇怪的错误消息)并且完全没必要。我甚至没有看到它提高可读性的地方 - 如果你已经在红宝石上待了一个多星期,那么#each应该很自然。

答案 3 :(得分:6)

这可能很明显,但如果有其他选择,我通常会避免使用eval。

答案 4 :(得分:6)

首先:如果是短暂的一次性脚本,或命令行上的单行或irb,我会破坏其中的许多规则。但我的大部分时间都花在中型或大型脚本或应用程序上。所以:

避免:

  • 使用class << self代码块进行类方法。这是一个可爱的技巧,但不比def self.foo好,而且可读性较差(特别是在第一页之后)。
  • for i in collection:改为使用collection.each
  • proc {...}:通常lambda {...}更好。
  • 类变量(例如@@foo)。它们是有问题的,通常可以毫不费力地用类级实例变量替换。
  • 导致警告的任何内容,最好是通过更严格ruby -w运行时发出警告的任何内容。如果您正在编写一个供他人使用的宝石,这一点尤其重要。
  • 'else'在'begin ... rescue ... end'块上。个人偏好:这是一个边缘案例过多,很少有人知道它存在或者它是如何运作的。
  • ObjectSpaceGC。你可能不需要去那里。你绝对不想去那里。
  • =begin=end多行评论。个人喜欢逐行评论。这些只会让我感到恶心。

使用它,但谨慎或作为最后的手段(并适当地评论):

    传入字符串时,
  • eval(或class_eval等)。有一些元编程技巧,你不能没有传递一个字符串。偶尔,字符串版本表现得更好(有时候很重要)。否则,我更喜欢为我的元编程发送实际ruby代码块。对于许多元编程任务,可以完全避免使用eval。
  • 在不是由我创建的类上添加或重新定义方法,并且可以由我控制之外的代码使用; a.k.a. monkey-patching。此规则主要用于较大的代码库和库;我很乐意并迅速为小型一次性脚本做出例外。我也会例外修复有缺陷的第三方库(尽管你升级时可能会在脚下射击!)。选择器命名空间(或类似的东西)将在很大程度上使ruby在这方面变得更好。也就是说,有时值得麻烦。 ; - )
  • 全局变量(类除外)。我甚至会将$ stdout作为参数传递给我的对象或方法,而不是直接使用它们。它使代码的重用更加容易和安全。有时你无法避免它(例如$0$:$$和其他环境变量,但即使这样你也可以限制你的使用量)。
    • 说到哪个,我更喜欢完全限制我对perlish符号全局变量的使用,但是如果需要使用它们,那么require "English"
  • break,redo,next,try:通常它们会使块,循环或方法比它本来更优雅。通常,当你一段时间没有看到这段代码时,它们会让你头疼几分钟。
  • __END__表示数据块。非常适合小型单文件脚本。对多文件应用无益。

不要使用它,但也不要真的避免它:

  • 尝试/捕获
  • 延续

我经常使用的东西,其他人可能不关心,或者我经常看不到:

  • 'and'和'or'关键字:它们与&&||的优先级不同,因此您需要谨慎对待它们。我发现它们的不同优先级非常有用。
  • 正则表达式黑魔法(假设我在单元测试中有一些例子)
  • HEREDOC字符串

答案 5 :(得分:1)

我真正讨厌的一件事是{}do ... end使用“不正当”的块。我似乎无法确切地找到我自己学习练习的位置,但通常可以接受单行块{}和多行块do ... end

正确使用:

[1, 2, 3, 4].map {|n| n * n }.inject(1) { |n,product| n * product }

[1, 2, 3, 4].inject do |n,product|
  n = n * n
  product = n * product
end

使用不当:

[1,2,3,4].map do |n| n * n end.inject(1) do |n,product| n * product end

[1, 2, 3, 4].inject { |n,product|
  n = n * n
  product = n * product
}

当然,所有这些都将执行给予576

答案 6 :(得分:1)

避免将太多方法调用链接在一起。 Ruby中将方法链接在一起非常普遍。

user.friends.each {|friend| friend.invite_to_party}

这似乎没问题,但打破了Law of Demeter

更正式地说,函数的Demeter法则要求对象O的方法M只能调用以下类型对象的方法:

  1. O本身
  2. M的参数
  3. 创建/实例化的任何对象 在M
  4. 之内
  5. O的直接组件对象
  6. 上面的例子并不完美,更好的解决方案是这样的:

    user.invite_friends_to_party
    

    示例的问题不是Ruby的错,但很容易产生违反Demeter法并使代码无法读取的代码。

    简而言之,请避免使用降低代码可读性的功能。您生成的代码易于阅读,这非常重要。非常重要。

答案 7 :(得分:0)

begin nil+234 rescue '' end

上面的语法是有效的,但你永远不应该使用它。

相关问题