对于ruby中的深层名称空间,如何最好地管理编码风格和范围操作符的麻烦?

对于ruby中的深层名称空间,如何最好地管理编码风格和范围操作符的麻烦?,ruby,coding-style,namespaces,scope,Ruby,Coding Style,Namespaces,Scope,我发现自己在与深层名称空间(>=depth of 4)作斗争,即使它们在逻辑上是合理的,以避免它们引起的一些麻烦 首先,我希望我的代码能够很好地适应文本编辑器窗口,而不必太宽。虽然2sp的ruby常规缩进确实有帮助,但这促使我使用scope操作符来避免所有嵌套缩进。但另一方面,使用scope操作符也会带来自己的一系列问题 首先,要在当前名称空间上下文的上游某处使用常量,必须使用该常量的完整名称空间,以便Ruby找到它。因为当我使用scope操作符时,名称空间的深度很深,引用常量和类的时间很长 r

我发现自己在与深层名称空间(>=depth of 4)作斗争,即使它们在逻辑上是合理的,以避免它们引起的一些麻烦

首先,我希望我的代码能够很好地适应文本编辑器窗口,而不必太宽。虽然2sp的ruby常规缩进确实有帮助,但这促使我使用scope操作符来避免所有嵌套缩进。但另一方面,使用scope操作符也会带来自己的一系列问题

首先,要在当前名称空间上下文的上游某处使用常量,必须使用该常量的完整名称空间,以便Ruby找到它。因为当我使用scope操作符时,名称空间的深度很深,引用常量和类的时间很长

require 'a/b'
class A::B::C
  FOO = 'hi'
end
class A::B::C::D
  # FOO # can't do this. raises NameError: uninitialized constant; would work fine if classes used nested format, but then the extra indent makes for wide code.
  A::B::C::FOO # must use full reference when using scopes, ugh. Depending on the real names of A,B,C, this could be rather long as well.
end
第二,我遇到了这样一种情况:我必须在我的类定义之后要求文件,我不喜欢这样做(我喜欢顶部的require语句),就像这样

# File: a/b/c.rb
require 'a/b'
# require 'a/b/c/d' # can't put it here, otherwise you get uninitialize const A::B::C when a/b/c/d.rb is getting interpreted.
class A::B::C
  def initialize
    @d = A::B::C::D.new 
  end
end
require 'a/b/c/d' # it bothers me putting requires anywhere but at the top

# File: a/b/c/d.rb
require 'a/b/c'
class A::B::C::D
end
必须有所付出。也许我只是需要让步,拓宽我的编辑器,坚持嵌套,或者我不知道如何最好地使用scope操作符在名称空间的上下文中工作

有人对我应该如何处理管理这些问题的深层名称空间有什么建议吗? 1.通过最小化缩进来降低代码宽度 2.在当前上下文上游定义常量时,能够仅使用常量名称(FOO)引用常量
3.将所有require语句保留在源代码文件的顶部

您在问题中自己回答了问题:-)

您试图避免代码中作用域过长的问题

只要看一看——如果您引用的常量位于范围层次结构的某个深处——您可以在技术上做什么:

使用Ruby电源

如果其中包含模块a和常量B,则可以尝试使用include a并访问常量B,而无需引用模块名称空间

但这可能不是您要寻找的-因为在本例中,您将包括模块,但它已经在那里定义

寻根

看,如果必须引用命名空间A::B::C::D中的常量,您的系统可能有错误的设计吗?OOP的目标通常是使数据和方法尽可能接近

你有两个选择:

  • 如果您感觉到气味,请改进系统的设计
  • 使用长引用,不管它们在你的编辑器中是如何出现的——只要重复一句简单的咒语:“我在这里有这个长引用,因为它应该在那里,并以这种方式看。”
  • 问题就会解决


    您不必使用类似于Java的基于包的名称空间。您可以选择一个更方便、更简单的名称空间

    名称空间和混合是两件不同的事情。我对名称空间的理解是“这个类/模块/常量只在父作用域上下文中有意义”。mixin将行为添加到类中。有时候我有5个深的,而且没有味道。例如,DBQuery::QueryExpression::ResultHandler::RelationGenerator::ConditionalOp。在其父范围之外使用这些类都没有意义。线索是ResultHandler本身并没有描述这个类。QueryExpressionResultHandler可以工作,但由于QueryExpression类已经存在,QueryExpression::ResultHandler工作得最好。我想知道为什么所有这些类/模块都在层次结构中。对我来说,如果有一个模块——比如ORM,以及其中的类DBQuery、QueryExpression等——那么你可以像ORM::DBQuery、ORM::ResultHandler那样访问它们,这是合理的,不是吗?ORM::ResultHandler不是很有描述性,因为它是一个QueryExpression ResultHandler。除此之外,像这样的深度并不少见。Rack具有Rack::Session::Cookie::Base64::Marshal;Turn有Test::Unit::UI::Console::TestRunner;RubyGems有Gem::Package::TarWriter::BoundedStream.wrt结束问题:问题出在哪里?没有评论帮我改进吗?你觉得我对清洁的渴望太过分了吗?还是我不清楚?简单地关闭并不酷。在浏览了其他著名项目的源代码之后,它似乎大多数都嵌套了它们的模块/类,因此没有遇到问题2和问题3。大量的缩进似乎并不困扰这些作者。我将遵循他们的风格,因为我倾向于将问题1视为邪恶中较小的一个。对于这个奇妙问题的收信人。。。谢谢你,杰克·霍尔斯!