比如我有一个函数,名称为"test_foo",放在一个名称为"test_foo.rb"中。
那在require "test_foo"
时,就产生混淆,可能会让人以为是一个名为TestFoo
的类。
因为按照
http://guides.rubygems.org/patterns/#consistent-naming
这里推荐的命名方式。用下划线来表示 CamelCase。这样不可避免的,Ruby 中函数命名通常都是带下划线的,那些单独的函数 rb 文件的命名就会令人易混淆。
我觉得 Ruby 采用这种命名文件 方式实在没有必要。说 Windows 文件名不区分大小写什么的,要是用大写字母就会导致移植的问题,这纯属瞎说,JAVA 不是照样文件名包含大写字母么,只要程序员在文件命名和 require 始终使用相同的名称就 OK 了,根本不存在 case-insensive 导致的移植问题。
将 Foo 这个 class 对应的文件命名成 Foo.rb,gem install Foo
,require "Foo"
,多一致,省得好多麻烦事。感觉这种文件名统一小写的习惯都是老了的程序员的心理阴影导致的
其实我对 Ruby 的包管理早就不顺眼了,stdlib 里有一个叫 OpenStruct 的东西,你要 require 它怎么法子?竟然是require 'ostruct'
,竟然是 ostruct !
此类乌龙不少,还有FileUtils
是require "fileutils"
。当然,也少不了require "English"
。还有唱反调的 GetoptLong:require 'getoptlong'
早在之前分析 Ruby 语法缺陷时,我就注意到 require 功能太弱。
require 功能只相当于 read_and_eval_once 这样一个函数,比load
函数只多了个“只加载一次”这功能。require 这种语法设计必然导致它的包命名及加载很不规范。
#4 楼 @jamchange 没听说什么语言的 stdlib 总是按套路出牌的 Java 标准库不是更加混乱吗? 在大部分情况下 我们不会把单独一个函数写在一个文件里 而是写在类里或是模块里。
#5 楼 @iBachue 我说的命名很不一致 是指文件命名和类名不一致啊,上面那些例子都在那。JAVA 根本不可能出现这种情况的。
比如,有个 util 方法是 Foo::Utils.say_hello
module Foo
module Utils
def self.say_hello
puts "Hello"
end
end
end
按 Gems 的规范,推荐文件名是"foo/utils/say_hello.rb",但你看这文件名,很容易会以为是 Foo::Utils::SayHello 这个类
明白了不?
PS:我感觉我最近在 RubyChina 的帖子,回复的都不对题啊,都不理解我在说什么啊啊啊啊。是我表达能力有问题吗?还是我表达的太跳跃了?
#9 楼 @jamchange 是的,我的意思已经很明确了,"foo/utils.rb"才是标准写法 对于函数拆开写的行为 我们通常会做子模块的 随随便便把类分在几个文件里不是好的 practice。
# foo/utils.rb
require 'foo/utils/sub'
module Foo
module Utils
extend Sub
def self.say_hello
puts 'Hello'
end
end
end
# foo/utils/sub.rb
module Foo
module Utils
module Sub
def sub_method
puts 'Sub method'
end
end
end
end
#12 楼 @jamchange 同 13 楼 其实你平时随便看看 railties,actionpack 和 activerecord 的代码就知道什么才是 Ruby Way 了,这方面的实践,世人早有定论。
另外对于 @iBachue 提到的不随便把类的方法拆成多个文件定义的,其实在 Ruby 中也挺常见的啊,有时需要重新 open 一个 class 再添些方法。连 C# 这样的语言都有 partial class,说明这种特性还是有需求的
特性本身是很常用啦,但是这招通常用于 Hack 别人的代码,如果代码从头到尾都是自己写的,这种方法都不是很常用了,当然偶尔出于什么特别目的也是有可能的。
看这个 to_json 方法扩展。 https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/to_json.rb
总有情形会遇到 rb 文件以方法名称命名的。对于这种情形也没啥规范,就看这个 method name 的人品能不能一读就知道是方法名了
require
和 java/python 里的 import
不是一回事,你可以 import 一个类,一个函数,但 require 的是文件...
ostruct 和 fileutils 是历史原因,但除了楼主也没有几个人感到困惑或不便...
如果规定了一个文件能且只能定义一个类,那么文件名和类名一致就可以了。这个规定也就在类非常多的时候有用... 但不是人人都在写这种包含成白上千个类的面条代码的。
#19 楼 @jamchange 其实这个有经验的人一看就明白了 core ext 类是 object,方法就是 to_json 了。。
#20 楼 @jamchange 其实里面有个 module 叫ActiveSupport::JSON::Encoding
...