1

我注意到 ruby​​ on rails 有一些有交流感觉的小宏。

__FILE__ and __LINE__

例如。这使得调试和生成唯一缓存键变得更加容易。

store = Rails.cache.fetch("#{__FILE__}|#{__LINE__}|#{self.store_id}")... 

当我可能会为一组给定的订单一遍又一遍地获得同一家商店时,最方便。

我想知道的是;我可以创建自己的宏/定义吗?预编译代码虽然有时不是一个好主意,但确实有它的位置。

问题:有没有办法在 ruby​​/rails 中创建 c 风格的宏?

4

2 回答 2

4

它们看起来像 C 但它们不是宏,它们只是对象,就像 ruby​​ 中的其他所有东西一样,它们特别具有确定当前正在解释的文件的名称和行号的能力。

C 宏只是对编译时可执行代码的引用。Ruby 是……完全与此相反 :-) Ruby 中的编译实际上是语法评估,然后是解释。如果像 C、C++ 和 Java 这样的语言是早期绑定的,而像 PHP 和 Python 这样的其他语言是后期绑定的,那么 ruby​​ 就错过了公共汽车,并且会在可能的最后时刻到达那里。

因此,如果您想创建自己的东西,请创建一个内部有东西的模块和/或类。您在内部创建的将是实例或类的变量、符号、常量或方法,可能是本地的,可能是公共的、受保护的或私有的。__FOO__使用特殊命名约定或其他(即使它们是有效名称)通常不是一种好的形式。

(回答结束......如果我听到你在问什么,也许这会帮助你实现所需的精神飞跃)......

我从 C 到 C++,再到 Java,然后到 Ruby。在为改革后的 Java 程序员提供了短暂的诊所后,我能够理解 ruby​​ 是多么强大。但是您确实必须考虑如何以不同的方式解决问题。

我强烈推荐这本书Eloquent Ruby,在这里链接到 Amazon

于 2012-11-29T02:15:08.147 回答
2

__FILE__并且本身__LINE__不是宏,它们是关键字(返回值)。String

话虽如此,您可以_定义以下划线或字符开头的常量和方法。例如:

__MICKEY__ = :mouse

现在,一个常量可以引用任何东西——一个字符串、一个表达式,甚至是一个代码块(a Procor lambda)或一个整体Class

这意味着您可以利用(可以说更强大的)运行时代码执行,而不是编译时宏扩展(Ruby,作为一种解释语言,实际上并没有“编译阶段”)。

例如,C++ 宏:

#define SUM(a, b, c) a + b + c

可以在 Ruby 中适当地近似为

def SUM(a, b, c); a + b + c; end

我说“近似”是因为 a) 在这种情况下,我们定义的是方法,而不是常量或宏,并且 b) C++ 宏在使用与预期数量不同的参数进行评估时仍然可以工作(因为 C++ 宏被扩展,意思是,就好像我们确实找到并替换了),而 Ruby 方法调用语义开始发挥作用,例如检查方法和参数的数量。

为了解决这个问题,在我们的特定示例中,我们可以做(可以说是更灵活的事情)

def SUM(*args); args.inject(:+); end

SUM(1, 2) # => 3
SUM(1, 2, 3, 5) # => 11

如您所见,通过利用 Ruby 的动态特性,您可以实现与 C++ 宏提供的类似(甚至可能更高)级别的表现力。

于 2012-11-29T02:43:03.010 回答