为了更好地了解 C++ 语言和语法的一些细节,我希望能够编写一个小型 C++ 程序,并查看编译器从中生成的 AST。
看起来clang过去有这个功能(-emit-asm),但它已经被删除了。
今天有没有简单的方法可以做到这一点?
最佳答案
这里有两个例子,一个简单的和一个讨厌的 (C++'s "most vexing parse")。
来自http://talkbinary.com/programming/c/fibonacci-in-c/ 的简单斐波那契程序解析为 C++ 代码:
int fib(int n) {
if ( n == 0 || n == 1 )
return n;
int fib1 = 0;
int fib2 = 1;
int fib = 0;
for ( int i = 2; i < n; i++ )
{
fib = fib1 + fib2;
fib1 = fib2;
fib2 = fib;
}
return fib;
}
我们的 DMS 软件再造工具包 (with full C++11/17 parser) 产生以下 AST:
C:\DMS\Domains\Cpp\GCC4\Tools\Parser\Source>run ..\DomainParser ++AST "C:\temp\fibonacci.cpp"
Cpp~GCC4 Domain Parser Version 2.5.15
Copyright (C) 1996-2013 Semantic Designs, Inc; All Rights Reserved; SD Confidential
Powered by DMS (R) Software Reengineering Toolkit
118 tree nodes in tree.
(translation_unit@Cpp~GCC4=2#4dc3a00^0 Line 1 Column 1 File C:/temp/fibonacci.cpp
(function_definition@Cpp~GCC4=1615#4dc39e0^1#4dc3a00:1 Line 1 Column 1 File C:/temp/fibonacci.cpp
(function_head@Cpp~GCC4=1627#4d89de0^1#4dc39e0:1 Line 1 Column 1 File C:/temp/fibonacci.cpp
(simple_type_specifier@Cpp~GCC4=1109#4d89920^1#4d89de0:1 Line 1 Column 1 File C:/temp/fibonacci.cpp
|('int'@Cpp~GCC4=2760#4d898c0^1#4d89920:1[Keyword:0] Line 1 Column 1 File C:/temp/fibonacci.cpp)'int'
)simple_type_specifier
(noptr_declarator@Cpp~GCC4=1401#4d89a80^1#4d89de0:2 Line 1 Column 5 File C:/temp/fibonacci.cpp
|(IDENTIFIER@Cpp~GCC4=2645#4d89900^1#4d89a80:1[`fib'] Line 1 Column 5 File C:/temp/fibonacci.cpp)IDENTIFIER
|('('@Cpp~GCC4=2885#4d89ac0^1#4d89a80:2[Keyword:0] Line 1 Column 8 File C:/temp/fibonacci.cpp)'('
|(parameter_declaration@Cpp~GCC4=1590#4d89e00^1#4d89a80:3 Line 1 Column 9 File C:/temp/fibonacci.cpp
| (simple_type_specifier@Cpp~GCC4=1109#4d89b20^1#4d89e00:1 Line 1 Column 9 File C:/temp/fibonacci.cpp
| ('int'@Cpp~GCC4=2760#4d89d60^1#4d89b20:1[Keyword:0] Line 1 Column 9 File C:/temp/fibonacci.cpp)'int'
| )simple_type_specifier
| (IDENTIFIER@Cpp~GCC4=2645#4d89b00^1#4d89e00:2[`n'] Line 1 Column 13 File C:/temp/fibonacci.cpp)IDENTIFIER
|)parameter_declaration
|(')'@Cpp~GCC4=2886#4d89bc0^1#4d89a80:4[Keyword:0] Line 1 Column 14 File C:/temp/fibonacci.cpp)')'
|(function_qualifiers@Cpp~GCC4=1417#4d89dc0^1#4d89a80:5 Line 1 Column 16 File C:/temp/fibonacci.cpp)function_qualifiers
)noptr_declarator
)function_head
(compound_statement@Cpp~GCC4=872#4dc39c0^1#4dc39e0:2 Line 1 Column 16 File C:/temp/fibonacci.cpp
('{'@Cpp~GCC4=2938#4d89f20^1#4dc39c0:1[Keyword:0] Line 1 Column 16 File C:/temp/fibonacci.cpp)'{'
(statement_seq@Cpp~GCC4=876#4dc3060^1#4dc39c0:2 Line 2 Column 5 File C:/temp/fibonacci.cpp
|(statement_seq@Cpp~GCC4=876#4dc3920^1#4dc3060:1 Line 2 Column 5 File C:/temp/fibonacci.cpp
| (statement_seq@Cpp~GCC4=876#4dc2880^1#4dc3920:1 Line 2 Column 5 File C:/temp/fibonacci.cpp
| (statement_seq@Cpp~GCC4=876#4dc2700^1#4dc2880:1 Line 2 Column 5 File C:/temp/fibonacci.cpp
| (statement_seq@Cpp~GCC4=876#4dc2640^1#4dc2700:1 Line 2 Column 5 File C:/temp/fibonacci.cpp
| |(selection_statement@Cpp~GCC4=892#4dc25c0^1#4dc2640:1 Line 2 Column 5 File C:/temp/fibonacci.cpp
| | ('if'@Cpp~GCC4=2753#4d89f40^1#4dc25c0:1[Keyword:0] Line 2 Column 5 File C:/temp/fibonacci.cpp)'if'
| | ('('@Cpp~GCC4=2885#4d89f60^1#4dc25c0:2[Keyword:0] Line 2 Column 8 File C:/temp/fibonacci.cpp)'('
| | (logical_or_expression@Cpp~GCC4=763#4dc2220^1#4dc25c0:3 Line 2 Column 10 File C:/temp/fibonacci.cpp
| | (equality_expression@Cpp~GCC4=696#4d89fa0^1#4dc2220:1 Line 2 Column 10 File C:/temp/fibonacci.cpp
| | (IDENTIFIER@Cpp~GCC4=2645#4d89d80^1#4d89fa0:1[`n'] Line 2 Column 10 File C:/temp/fibonacci.cpp)IDENTIFIER
| | ('=='@Cpp~GCC4=2918#4d89da0^1#4d89fa0:2[Keyword:0] Line 2 Column 12 File C:/temp/fibonacci.cpp)'=='
| | (INT_LITERAL@Cpp~GCC4=2809#4d89fe0^1#4d89fa0:3[0] Line 2 Column 15 File C:/temp/fibonacci.cpp)INT_LITERAL
| | )equality_expression
| | ('||'@Cpp~GCC4=2922#4d89f80^1#4dc2220:2[Keyword:0] Line 2 Column 17 File C:/temp/fibonacci.cpp)'||'
| | (equality_expression@Cpp~GCC4=696#4dc2200^1#4dc2220:3 Line 2 Column 20 File C:/temp/fibonacci.cpp
| | (IDENTIFIER@Cpp~GCC4=2645#4dc2180^1#4dc2200:1[`n'] Line 2 Column 20 File C:/temp/fibonacci.cpp)IDENTIFIER
| | ('=='@Cpp~GCC4=2918#4dc21a0^1#4dc2200:2[Keyword:0] Line 2 Column 22 File C:/temp/fibonacci.cpp)'=='
| | (INT_LITERAL@Cpp~GCC4=2809#4dc21c0^1#4dc2200:3[1] Line 2 Column 25 File C:/temp/fibonacci.cpp)INT_LITERAL
| | )equality_expression
| | )logical_or_expression
| | (')'@Cpp~GCC4=2886#4dc21e0^1#4dc25c0:4[Keyword:0] Line 2 Column 27 File C:/temp/fibonacci.cpp)')'
| | (jump_statement@Cpp~GCC4=983#4dc2440^1#4dc25c0:5 Line 3 Column 9 File C:/temp/fibonacci.cpp
| | ('return'@Cpp~GCC4=2778#4dc2340^1#4dc2440:1[Keyword:0] Line 3 Column 9 File C:/temp/fibonacci.cpp)'return'
| | (IDENTIFIER@Cpp~GCC4=2645#4dc2360^1#4dc2440:2[`n'] Line 3 Column 16 File C:/temp/fibonacci.cpp)IDENTIFIER
| | (';'@Cpp~GCC4=2937#4dc2400^1#4dc2440:3[Keyword:0] Line 3 Column 17 File C:/temp/fibonacci.cpp)';'
| | )jump_statement
| |)selection_statement
| |(simple_declaration@Cpp~GCC4=1033#4dc2620^1#4dc2640:2 Line 5 Column 5 File C:/temp/fibonacci.cpp
| | (simple_type_specifier@Cpp~GCC4=1109#4dc23c0^1#4dc2620:1 Line 5 Column 5 File C:/temp/fibonacci.cpp
| | ('int'@Cpp~GCC4=2760#4dc2520^1#4dc23c0:1[Keyword:0] Line 5 Column 5 File C:/temp/fibonacci.cpp)'int'
| | )simple_type_specifier
| | (init_declarator@Cpp~GCC4=1380#4dc23a0^1#4dc2620:2 Line 5 Column 9 File C:/temp/fibonacci.cpp
| | (IDENTIFIER@Cpp~GCC4=2645#4dc2460^1#4dc23a0:1[`fib1'] Line 5 Column 9 File C:/temp/fibonacci.cpp)IDENTIFIER
| | (initializer@Cpp~GCC4=1639#4dc2380^1#4dc23a0:2 Line 5 Column 14 File C:/temp/fibonacci.cpp
| | ('='@Cpp~GCC4=2893#4dc23e0^1#4dc2380:1[Keyword:0] Line 5 Column 14 File C:/temp/fibonacci.cpp)'='
| | (INT_LITERAL@Cpp~GCC4=2809#4dc2680^1#4dc2380:2[0] Line 5 Column 16 File C:/temp/fibonacci.cpp)INT_LITERAL
| | )initializer
| | )init_declarator
| | (';'@Cpp~GCC4=2937#4dc26a0^1#4dc2620:3[Keyword:0] Line 5 Column 17 File C:/temp/fibonacci.cpp)';'
| |)simple_declaration
| )statement_seq
| (simple_declaration@Cpp~GCC4=1033#4dc25a0^1#4dc2700:2 Line 6 Column 5 File C:/temp/fibonacci.cpp
| |(simple_type_specifier@Cpp~GCC4=1109#4dc26c0^1#4dc25a0:1 Line 6 Column 5 File C:/temp/fibonacci.cpp
| | ('int'@Cpp~GCC4=2760#4dc2600^1#4dc26c0:1[Keyword:0] Line 6 Column 5 File C:/temp/fibonacci.cpp)'int'
| |)simple_type_specifier
| |(init_declarator@Cpp~GCC4=1380#4dc2560^1#4dc25a0:2 Line 6 Column 9 File C:/temp/fibonacci.cpp
| | (IDENTIFIER@Cpp~GCC4=2645#4dc2660^1#4dc2560:1[`fib2'] Line 6 Column 9 File C:/temp/fibonacci.cpp)IDENTIFIER
| | (initializer@Cpp~GCC4=1639#4dc2540^1#4dc2560:2 Line 6 Column 14 File C:/temp/fibonacci.cpp
| | ('='@Cpp~GCC4=2893#4dc26e0^1#4dc2540:1[Keyword:0] Line 6 Column 14 File C:/temp/fibonacci.cpp)'='
| | (INT_LITERAL@Cpp~GCC4=2809#4dc2740^1#4dc2540:2[1] Line 6 Column 16 File C:/temp/fibonacci.cpp)INT_LITERAL
| | )initializer
| |)init_declarator
| |(';'@Cpp~GCC4=2937#4dc2760^1#4dc25a0:3[Keyword:0] Line 6 Column 17 File C:/temp/fibonacci.cpp)';'
| )simple_declaration
| )statement_seq
| (simple_declaration@Cpp~GCC4=1033#4dc2860^1#4dc2880:2 Line 7 Column 5 File C:/temp/fibonacci.cpp
| (simple_type_specifier@Cpp~GCC4=1109#4dc27c0^1#4dc2860:1 Line 7 Column 5 File C:/temp/fibonacci.cpp
| |('int'@Cpp~GCC4=2760#4dc2580^1#4dc27c0:1[Keyword:0] Line 7 Column 5 File C:/temp/fibonacci.cpp)'int'
| )simple_type_specifier
| (init_declarator@Cpp~GCC4=1380#4dc2820^1#4dc2860:2 Line 7 Column 9 File C:/temp/fibonacci.cpp
| |(IDENTIFIER@Cpp~GCC4=2645#4dc2720^1#4dc2820:1[`fib'] Line 7 Column 9 File C:/temp/fibonacci.cpp)IDENTIFIER
| |(initializer@Cpp~GCC4=1639#4dc2800^1#4dc2820:2 Line 7 Column 13 File C:/temp/fibonacci.cpp
| | ('='@Cpp~GCC4=2893#4dc27e0^1#4dc2800:1[Keyword:0] Line 7 Column 13 File C:/temp/fibonacci.cpp)'='
| | (INT_LITERAL@Cpp~GCC4=2809#4dc28c0^1#4dc2800:2[0] Line 7 Column 15 File C:/temp/fibonacci.cpp)INT_LITERAL
| |)initializer
| )init_declarator
| (';'@Cpp~GCC4=2937#4dc28e0^1#4dc2860:3[Keyword:0] Line 7 Column 16 File C:/temp/fibonacci.cpp)';'
| )simple_declaration
| )statement_seq
| (iteration_statement@Cpp~GCC4=941#4dc3980^1#4dc3920:2 Line 9 Column 5 File C:/temp/fibonacci.cpp
| ('for'@Cpp~GCC4=2749#4dc2840^1#4dc3980:1[Keyword:0] Line 9 Column 5 File C:/temp/fibonacci.cpp)'for'
| ('('@Cpp~GCC4=2885#4dc28a0^1#4dc3980:2[Keyword:0] Line 9 Column 9 File C:/temp/fibonacci.cpp)'('
| (simple_declaration@Cpp~GCC4=1033#4dc2a20^1#4dc3980:3 Line 9 Column 11 File C:/temp/fibonacci.cpp
| (simple_type_specifier@Cpp~GCC4=1109#4dc2940^1#4dc2a20:1 Line 9 Column 11 File C:/temp/fibonacci.cpp
| |('int'@Cpp~GCC4=2760#4dc2900^1#4dc2940:1[Keyword:0] Line 9 Column 11 File C:/temp/fibonacci.cpp)'int'
| )simple_type_specifier
| (init_declarator@Cpp~GCC4=1380#4dc29e0^1#4dc2a20:2 Line 9 Column 15 File C:/temp/fibonacci.cpp
| |(IDENTIFIER@Cpp~GCC4=2645#4dc2920^1#4dc29e0:1[`i'] Line 9 Column 15 File C:/temp/fibonacci.cpp)IDENTIFIER
| |(initializer@Cpp~GCC4=1639#4dc29c0^1#4dc29e0:2 Line 9 Column 17 File C:/temp/fibonacci.cpp
| | ('='@Cpp~GCC4=2893#4dc2960^1#4dc29c0:1[Keyword:0] Line 9 Column 17 File C:/temp/fibonacci.cpp)'='
| | (INT_LITERAL@Cpp~GCC4=2809#4dc2a40^1#4dc29c0:2[2] Line 9 Column 19 File C:/temp/fibonacci.cpp)INT_LITERAL
| |)initializer
| )init_declarator
| (';'@Cpp~GCC4=2937#4dc29a0^1#4dc2a20:3[Keyword:0] Line 9 Column 20 File C:/temp/fibonacci.cpp)';'
| )simple_declaration
| (relational_expression@Cpp~GCC4=684#4dc2b60^1#4dc3980:4 Line 9 Column 22 File C:/temp/fibonacci.cpp
| (IDENTIFIER@Cpp~GCC4=2645#4dc2a00^1#4dc2b60:1[`i'] Line 9 Column 22 File C:/temp/fibonacci.cpp)IDENTIFIER
| ('<'@Cpp~GCC4=2899#4dc2a80^1#4dc2b60:2[Keyword:0] Line 9 Column 24 File C:/temp/fibonacci.cpp)'<'
| (IDENTIFIER@Cpp~GCC4=2645#4dc2aa0^1#4dc2b60:3[`n'] Line 9 Column 26 File C:/temp/fibonacci.cpp)IDENTIFIER
| )relational_expression
| (';'@Cpp~GCC4=2937#4dc2b40^1#4dc3980:5[Keyword:0] Line 9 Column 27 File C:/temp/fibonacci.cpp)';'
| (postfix_expression@Cpp~GCC4=406#4dc2b20^1#4dc3980:6 Line 9 Column 29 File C:/temp/fibonacci.cpp
| (IDENTIFIER@Cpp~GCC4=2645#4dc2e60^1#4dc2b20:1[`i'] Line 9 Column 29 File C:/temp/fibonacci.cpp)IDENTIFIER
| ('++'@Cpp~GCC4=2897#4dc2ae0^1#4dc2b20:2[Keyword:0] Line 9 Column 30 File C:/temp/fibonacci.cpp)'++'
| )postfix_expression
| (')'@Cpp~GCC4=2886#4dc2b00^1#4dc3980:7[Keyword:0] Line 9 Column 33 File C:/temp/fibonacci.cpp)')'
| (compound_statement@Cpp~GCC4=872#4dc38e0^1#4dc3980:8 Line 10 Column 5 File C:/temp/fibonacci.cpp
| ('{'@Cpp~GCC4=2938#4dc2b80^1#4dc38e0:1[Keyword:0] Line 10 Column 5 File C:/temp/fibonacci.cpp)'{'
| (statement_seq@Cpp~GCC4=876#4dc3900^1#4dc38e0:2 Line 11 Column 9 File C:/temp/fibonacci.cpp
| |(statement_seq@Cpp~GCC4=876#4dc2f20^1#4dc3900:1 Line 11 Column 9 File C:/temp/fibonacci.cpp
| | (expression_statement@Cpp~GCC4=869#4dc3080^1#4dc2f20:1 Line 11 Column 9 File C:/temp/fibonacci.cpp
| | (assignment_expression@Cpp~GCC4=809#4dc33a0^1#4dc3080:1 Line 11 Column 9 File C:/temp/fibonacci.cpp
| | (IDENTIFIER@Cpp~GCC4=2645#4dc2ba0^1#4dc33a0:1[`fib'] Line 11 Column 9 File C:/temp/fibonacci.cpp)IDENTIFIER
| | ('='@Cpp~GCC4=2893#4dc2bc0^1#4dc33a0:2[Keyword:0] Line 11 Column 13 File C:/temp/fibonacci.cpp)'='
| | (additive_expression@Cpp~GCC4=593#4dc3000^1#4dc33a0:3 Line 11 Column 15 File C:/temp/fibonacci.cpp
| | |(IDENTIFIER@Cpp~GCC4=2645#4dc2be0^1#4dc3000:1[`fib1'] Line 11 Column 15 File C:/temp/fibonacci.cpp)IDENTIFIER
| | |('+'@Cpp~GCC4=2902#4dc2e80^1#4dc3000:2[Keyword:0] Line 11 Column 20 File C:/temp/fibonacci.cpp)'+'
| | |(IDENTIFIER@Cpp~GCC4=2645#4dc2ea0^1#4dc3000:3[`fib2'] Line 11 Column 22 File C:/temp/fibonacci.cpp)IDENTIFIER
| | )additive_expression
| | )assignment_expression
| | (';'@Cpp~GCC4=2937#4dc2ec0^1#4dc3080:2[Keyword:0] Line 11 Column 26 File C:/temp/fibonacci.cpp)';'
| | )expression_statement
| | (expression_statement@Cpp~GCC4=869#4dc2f00^1#4dc2f20:2 Line 12 Column 9 File C:/temp/fibonacci.cpp
| | (assignment_expression@Cpp~GCC4=809#4dc3740^1#4dc2f00:1 Line 12 Column 9 File C:/temp/fibonacci.cpp
| | (IDENTIFIER@Cpp~GCC4=2645#4dc2ee0^1#4dc3740:1[`fib1'] Line 12 Column 9 File C:/temp/fibonacci.cpp)IDENTIFIER
| | ('='@Cpp~GCC4=2893#4dc3400^1#4dc3740:2[Keyword:0] Line 12 Column 14 File C:/temp/fibonacci.cpp)'='
| | (IDENTIFIER@Cpp~GCC4=2645#4dc3340^1#4dc3740:3[`fib2'] Line 12 Column 16 File C:/temp/fibonacci.cpp)IDENTIFIER
| | )assignment_expression
| | (';'@Cpp~GCC4=2937#4dc2fa0^1#4dc2f00:2[Keyword:0] Line 12 Column 20 File C:/temp/fibonacci.cpp)';'
| | )expression_statement
| |)statement_seq
| |(expression_statement@Cpp~GCC4=869#4dc2fe0^1#4dc3900:2 Line 13 Column 9 File C:/temp/fibonacci.cpp
| | (assignment_expression@Cpp~GCC4=809#4dc3940^1#4dc2fe0:1 Line 13 Column 9 File C:/temp/fibonacci.cpp
| | (IDENTIFIER@Cpp~GCC4=2645#4dc38a0^1#4dc3940:1[`fib2'] Line 13 Column 9 File C:/temp/fibonacci.cpp)IDENTIFIER
| | ('='@Cpp~GCC4=2893#4dc37a0^1#4dc3940:2[Keyword:0] Line 13 Column 14 File C:/temp/fibonacci.cpp)'='
| | (IDENTIFIER@Cpp~GCC4=2645#4dc3700^1#4dc3940:3[`fib'] Line 13 Column 16 File C:/temp/fibonacci.cpp)IDENTIFIER
| | )assignment_expression
| | (';'@Cpp~GCC4=2937#4dc38c0^1#4dc2fe0:2[Keyword:0] Line 13 Column 19 File C:/temp/fibonacci.cpp)';'
| |)expression_statement
| )statement_seq
| ('}'@Cpp~GCC4=2939#4dc2fc0^1#4dc38e0:3[Keyword:0] Line 14 Column 5 File C:/temp/fibonacci.cpp)'}'
| )compound_statement
| )iteration_statement
|)statement_seq
|(jump_statement@Cpp~GCC4=983#4dc3040^1#4dc3060:2 Line 16 Column 5 File C:/temp/fibonacci.cpp
| ('return'@Cpp~GCC4=2778#4dc3960^1#4dc3040:1[Keyword:0] Line 16 Column 5 File C:/temp/fibonacci.cpp)'return'
| (IDENTIFIER@Cpp~GCC4=2645#4dc3500^1#4dc3040:2[`fib'] Line 16 Column 12 File C:/temp/fibonacci.cpp)IDENTIFIER
| (';'@Cpp~GCC4=2937#4dc3540^1#4dc3040:3[Keyword:0] Line 16 Column 15 File C:/temp/fibonacci.cpp)';'
|)jump_statement
)statement_seq
('}'@Cpp~GCC4=2939#4dc3560^1#4dc39c0:3[Keyword:0] Line 17 Column 1 File C:/temp/fibonacci.cpp)'}'
)compound_statement
)function_definition
)translation_unit
Exiting with final status 0.
C:\DMS\Domains\Cpp\GCC4\Tools\Parser\Source>
DMS 可以为此生成 XML 版本。
对于 truly vexing example of C++ :
template<bool> struct a_t;
template<> struct a_t<true> {
template<int> struct b {};
};
template<> struct a_t<false> {
enum { b };
};
typedef a_t<sizeof(void*)==sizeof(int)> a;
enum { c, d };
int main() {
a::b<c>d; // declaration or expression?
}
... DMS 生成以下树,具有多种解释 最后一条语句(用点绘制;您的浏览器可能有一个“查看图像”让您看到更大的版本):
显示的示例恰好是针对 C++ 的 GCC 方言。 DMS 还可以解析 Microsoft Visual Studio C++(截至 2015 年 6 月,处理 C++14 和所有 MSVC 2013,我们正在检查与 MSVC 2015 的兼容性)。
[2018 年 6 月编辑:现在处理 C++17。标准中的暗角数量令人惊叹。]
单独获取解析树通常不是很有用。您还需要其他工件,例如 symbol table和控制/数据流事实。 DMS C++ 前端将所有这些作为工具可访问的 AST 数据属性生成。 (使用这些符号表,C++ 前端会解析上例中的哪些子解析是有效的,并删除无效的子树。)
有时解析语言的(格式良好的)子字符串很有用。 DMS 解析引擎可以做到这一点;你没有解析整个编译单元。
关于c++ - 从 C++ 代码中获取人类可读的 AST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17388771/
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el