什么是Ruby代码的“太聪明”的例子?

时间:2009-04-02 05:36:34

标签: ruby

我正和一些程序员朋友讨论,他们说他们看到Ruby程序员(特别是)生成了很多“太聪明”的代码。所以我想知道那会是什么样的?我指的是在一个简单易用的东西中不必要地使用一个模糊的语言特征。知道任何好的Ruby例子吗?

14 个答案:

答案 0 :(得分:37)

在对你的问题作出直接回答后,我也想对这个前提提出质疑;每当一组程序员以这种方式描述另一种语言的用户时,他们可能会告诉你更多关于他们自己的信息,而不是他们所描述的社区。 例如,你可能会指责程序员过于沉迷于低级别的细节,或者因为他们对功能纯度的渴望而蒙羞的程序员;为了简洁等等,你可以恕我直言,当你这样做的时候,你可以通过判断因果关系。

当我想编写一个以某种风格表达最佳的程序时,我会尝试选择支持该风格的语言。有时候你需要一个可以让你做一些不寻常的事情的工具,而且这样一个像ruby这样的语言的任务和数学的mathematica或者工具包中的浏览器操作的javascript一样有价值。如果我想玩排版,我会跳到postscript ,因为这是最好的。

这就像是说“你有没有注意到使用电钻的人总是在挖洞?”这是真的,但有点遗漏了这一点。

答案 1 :(得分:10)

class Tree
  def initialize*d;@d,=d;end
  def to_s;@l||@r?"<#{@d},<#{@l}>,<#{@r}>>":@d;end
  def total;(@d.is_a?(Numeric)?@d:0)+(@l?@l.total: 0)+(@r?@r.total: 0);end
  def insert d
    alias g instance_variable_get
    p=lambda{|s,o|d.to_s.send(o,@d.to_s)&&
      (g(s).nil??instance_variable_set(s,Tree.new(d)):g(s).insert(d))}
    @d?p[:@l,:<]||p[:@r,:>]:@d=d
  end
end

答案 2 :(得分:7)

双重爆炸:!!某事

我不会写它的作用。忘记你曾经看过这种语法。

答案 3 :(得分:6)

任何元编程的使用,如果没有想到是否有更好的方法来使用该语言的正常,非'''成语来实现这一点,我往往会觉得很烦人。

对“DRY”的痴迷(不要重复自己),其中一些恶魔般的元编程意大利面被调用,以避免重复自己,比如说,两次简单,实际上更直接和可读性比 - 替代时尚。

特别使用'eval'。随着元编程的发展,在尝试其他一切之后,这个应该是你绝对的最后手段。例如,许多rubyists似乎没有听说过Class#define_method。

答案 4 :(得分:5)

yaml.rb的输出阶段;这就是我合着zaml.rb的原因。标准的yaml版本可以进行各种各样的元编程(它最初是为什么 - 幸运僵硬,我一般都很钦佩)但是用一个直接映射到类树的直接分层版本替换它我们能够消除几个O(n ^ 3)个案例,导致感兴趣的案例加速十倍,修复了几个错误,并且在一小部分代码中这样做。

另外,即使不是红宝石大师的人也可以看到它的作用。

答案 5 :(得分:5)

本文中的许多示例似乎都符合条件:

21 Ruby Tricks You Should Be Using In Your Own Code

该文章的标题有点赠品,因为它的内容是“应该”而不是“不应该”。代码“应该”是透明的。代码“不应该”是棘手的。

答案 6 :(得分:3)

我不确定这是否合格“太聪明”,但我看到的代码让我想知道作者是天才还是白痴。一个开发人员似乎有一条规则,即任何方法都不应该有两行以上的代码。这使得调用堆栈非常深入,并使调试变得相当困难。好处是他的整体设计非常抽象,甚至远距离优雅。

答案 7 :(得分:3)

Cucumber(或RSpec Stories

引自上述RSpec Stories链接:

  

基于纯文本描述   应用程序行为,它让你   写好集成测试   重用和良好的诊断报告。

     

例如,这是我写给的一个故事   检查登录过程。

Story: login as an existing user
    As an unauthenticated user
    I want to log in to Expectnation
    So I can see my account details

    Scenario: login details are correct
            Given an event provider
            And my test@example.org account
            When I log in with email test@example.org and password foofoo
            Then I will be logged in
            And I will be shown the account page
     

诸如“给定”,“何时”和   “然后”是赛跑者的线索   执行一些代码。在故事的背后   坐在一系列步骤。这是一个   这个测试的几个步骤:

  Given "my $email account" do |email|
    @user = find_or_create_user_by_email({:email => email,
      :password => 'foofoo',
      :password_confirmation => 'foofoo'})
  end

  When "I log in with email $email and password $password" do |email, password|
    post '/user/account/authenticate',
      :user => {:email => email, :password => password}
  end
     

注意一下巧妙的字符串   匹配允许您传递参数   来自故事散文。

     

通过一点点抽搐,散文故事然后作为代码和测试执行。

答案 8 :(得分:2)

这取决于。 (我喜欢“这取决于”问题)

这取决于作者和读者的知识。我曾经认为使用Symbol#to_proc in Rails是不必要的晦涩,例如,更喜欢

a.map { |e| e.downcase }

a.map(&:downcase)

现在,当我阅读它时,我很高兴,尽管我仍然不想写它。

有一些图书馆(Rails和其他)的地方,我觉得过度和自我放纵的元编程可能已经发生但是“太聪明”和“确实非常聪明”之间的划分往往是纸上薄的。 DSL是一个很好的领域:在类中提供“宏”的方式(想想ActiveRecord :: Base或ActionController :: Base等所有声明性的优点)对于相对新手来说很难理解,并且很可能看起来过于聪明。它对我有用。现在我发现自己引用相同的代码作为指导,因为我实现了类似的功能。

答案 9 :(得分:1)

method_missing可以被滥用,当你编写代码3个月后必须修复错误时,这可能会导致你脱头而出。

答案 10 :(得分:1)

看看Markaby的来源。精神错乱。

答案 11 :(得分:1)

你不应该从方法到方法再到方法试图弄清楚到底是什么在做什么,唯一的目的是不重复几行代码。过于专注于LOC计数和超瘦的方法当时可能会感觉很酷,但是对于试图调试或遵循代码的其他人来说是非常耗时的(而且有些人可能是几个月后)。

答案 12 :(得分:0)

比较

if MODELS.keys.inject(true) {|b, klass| b and klass.constantize.columns.map(&:name).include? association.options [:foreign_key]} then 
  # ... 
end

1行(if),132个字符,132 avg len,22.9 fl og

VS

fk = association.options[:foreign_key] 
columns = MODELS.keys.map { |key| key.constantize.columns.map { |c| c.name } } 
if columns.all? {|column| column.include? fk} then 
  # ... 
end

4行,172个字符,43个平均字符,15.9个字符

也快得多。

原作者实际上认为第一版的可维护性。

答案 13 :(得分:0)

最近发现了这个怪物:

def id
  unless defined?(@id)
    @id = if id = local_body.to_s[/(?:#\s*|@[[:punct:]]?)#{URL_REGEX}/,1]
            id.to_i
          end
  end
  @id
end

不是我不同意缓存计算,它可能会更加明确。