我正在尝试一种在编译时将元素添加到结构中的方法,但是要在另一个文件中定义它。例如:
defA.h:
def add_card
if current_user.stripe_id.blank?
customer = Stripe::Customer.create(
email: current_user.email
)
current_user.stripe_id = customer.id
current_user.save
customer.sources.create(source: params[:stripeToken])
else
customer = Stripe::Customer.retrieve(current_user.stripe_id)
customer.source = params[:stripeToken]
customer.save
end
flash[:notice] = "Your card is saved."
redirect_to payment_method_path
rescue Stripe::CardError => e
flash[:alert] = e.message
redirect_to payment_method_path
end
otherfile.c:
typedef struct A {
int element1;
int element2;
} A;
会导致:
#include "defA.h"
typedef struct B {
int element1;
} B;
ADD_ELEMENT_TO(A, B, element3)
有人能想到实现这一目标或类似目标的方法吗?我希望能够通过选择编译struct A {
int element1;
int element2;
B element3;
};
或不编译其余版本来控制它。
答案 0 :(得分:2)
任何使用C预处理器功能的解决方案都会在声明结构的地方弄得一团糟。例如:
主要来源/标题:
#include "SpecialSauce.h"
…
typedef struct A {
int element1;
int element2;
SpecialStuff
} A;
如果客户刚刚购买了基本软件,则SpecialSauce.h包含:
#define SpecialStuff
如果客户支付额外费用,SpecialSauce.h包含:
#define SpecialStuff int element3;
当然,根据所使用的软件版本,将需要使用或不使用element3
的代码。
所有这些都可以通过预处理器指令进行控制,并且通过给予适当的注意,通常可以使它不会太混乱。但是商业压力通常会阻止这种情况,并导致软件变得更加混乱,并且维护被忽略。因此,这类纠缠将变得丑陋且昂贵。
另一种选择是保留主源文件,并使用它们来生成具有选定选项的源文件。仅将生成的源文件提供给客户,并且他们不会具有难看的预处理条件。但是,这需要软件来处理主源文件,而主文件本身必须维护,并且主源文件仍必须具有某种条件,由于它们在您的控制之下,因此您可能会保持良好状态,但是,现实世界中的软件又有变得混乱的趋势。