我希望能够静态分析我的代码。也就是说,从文件的纯文本中了解每个函数和变量的来源。 IDE和文本编辑器插件在跟踪每个符号的来源时也能更好地工作。
例如,如果我有这样的应用程序代码:
#...
Y.some_method()
#...
然后我想在页面的某个地方的include / import / require / extend / def语句中看到Y
。
在我使用的其他语言中,可以明确选择命名空间的哪些子部分引入当前上下文。
的Python:
from X import Y
Haskell中:
import X (Y)
药剂:
alias X.Y, as: Y
虽然可以在Python中导入所有包含的名称,但“通配符导入”is frowned upon:
from X import *
“......他们不清楚命名空间中存在哪些名称,使读者和许多自动化工具都感到困惑。”
在Ruby中,似乎这种完全隐含的“通配符”方式是引入包含名称的唯一方式:
include X
这使得Y
可用,但有哪些方法可以明确这一点? docs for Ruby include
没有显示任何选项。
我真正喜欢在Ruby中做的事情就像其中之一:
from X include Y
include X::Y as Y
到目前为止,我提出的最好的是:
require 'x/y' ; Y = X::Y
这是a crazy hack在另一个问题的答案中可以实现此目的。
答案 0 :(得分:2)
试试这个。但我同意@tadman你应该考虑用Ruby方式做这件事。
Object.define_singleton_method(:include) do |*mths, from: nil|
mod = from || mths.first
mod = mod.dup
if from
all_mths = mod.instance_methods
(all_mths - mths).each { |mth| mod.send :undef_method, mth }
end
super(mod)
end
module Foobar
def foo
puts :foo
end
def bar
puts :bar
end
end
class Abc
include Foobar
end
Abc.new.foo # => 'foo'
Abc.new.bar # => 'foo'
class AbcWithoutBar
include :foo, from: Foobar
end
AbcWithoutBar.new.foo # => 'foo'
AbcWithoutBar.new.bar # => NoMethodError
答案 1 :(得分:2)
Ruby始终执行您require
由于没有部分执行文件,因此不能部分require
。
当你require
一个功能时,Ruby使用$:
中的加载路径找到相应的文件,然后对$"
中加载的文件列表进行双重检查,如果文件还没有已加载执行文件。
Ruby是一种动态语言,推理其源代码的最佳方式是暂停正在运行的程序而不是静态。实际上,即使class
和def
也不是声明,而只是在运行时执行的方法调用。考虑一下这个人为的例子
class Surprise < [Array, Hash, Fixnum, Object].sample
end
如果您想知道定义方法或类的位置,请最好使用pry
。您可以要求pry
,然后使用binding.pry
停止源代码中的任何位置,然后选择检查对象和源代码。两个最有用的命令是ls
和$
ls
打印对象或类的所有方法$
打印方法的文件位置和源代码