在 ruby​​ C 扩展中类型检查选项哈希值时的最佳实践是什么?

发布于 2024-11-18 22:06:23 字数 584 浏览 4 评论 0原文

我正在为 ruby​​ 开发一个 C 扩展,我正在访问的 C 库中的函数之一接收一个选项结构,该结构似乎自然地转换为 ruby​​ 世界中的选项哈希。

当 ruby​​ 端的哈希没有为给定选项定义值时,该结构将使用已知的默认值进行初始化。在 C 方面,我有一些类似的想法:

VALUE tmp;

tmp = rb_hash_aref(r_hash, rb_str_new2("opt1"));

if(TYPE(tmp) == T_STRING){
  strcpy (c_learn_param->opt1, StringValuePtr(tmp));
}else{
  strcpy (c_learn_param->opt1, "default value 1");
}

现在我的问题是,当一个选项具有定义的值但 ruby​​ 类型在 C 中没有意义时。

即使对于可选值,我也应该引发类型错误吗?这似乎有点过分了,我应该回到默认值吗?回退到默认值的问题是用户传递 {"opt1" =>; 123 } 将看到与他没有定义 opt1 相同的行为,这似乎是一个坏主意,我应该回退并打印 ruby​​ 警告吗? (人们甚至读过它们吗?)。

I'm developing a C extension for ruby, one of the functions from the C library I'm accessing receives an options struct which seems to be naturally translate to an options hash in ruby-world.

The struct is being initialized with known default values when the hash on the ruby side does not define a value for a given option. On the C side I have some along these lines:

VALUE tmp;

tmp = rb_hash_aref(r_hash, rb_str_new2("opt1"));

if(TYPE(tmp) == T_STRING){
  strcpy (c_learn_param->opt1, StringValuePtr(tmp));
}else{
  strcpy (c_learn_param->opt1, "default value 1");
}

Now my problem is when an option has a defined value but the ruby type does not make sense in C.

Should I raise type error even for an optional value? that seems overkill, should I fall back to a default? the problem with falling back to a default is a user passing {"opt1" => 123 } will see the same behaviour as if he had not defined opt1 which seems like a bad idea, should I fall back and print a ruby warning? (do people even read them?).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一刻暧昧 2024-11-25 22:06:23

您可能应该至少接受一个符号或一个字符串,因为它们在实践中几乎可以互换使用(因此 ActiveSupport::HashWithIn DifferentAccess)。

根据您的具体情况,在 tmp 上调用 to_s 并让其中的任何内容都可以通过这种方式转换为字符串可能是有意义的。但是,如果只接受 String 或 Symbol 才有意义,那么引发 TypeError 是完全明智的做法。

对输入尽可能灵活但对输出严格通常是一个好主意,并且有助于建立友好的库。

如果人们不阅读警告,那么当出现问题时,这就是他们自己的错,而你完全有权利傻笑并说“我告诉过你了”。

You should probably accept at least a Symbol or a String as they are, in practice, used nearly interchangeably (hence ActiveSupport::HashWithIndifferentAccess).

Depending on your specific situation, it might make sense to call to_s on your tmp and let anything in that can be converted to a String that way. However, if it only makes sense to accept a String or Symbol then raising a TypeError is a perfectly sensible thing to do.

Being as flexible as possible with your inputs but strict with your outputs is usually a good idea and makes for friendly libraries.

If people don't read warnings then it is their own fault when things go wrong and you're well within your rights to smirk and say "I told you so".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文