我试图了解String#capitalize!
内部如何运作。我可以创建一个哈希。给定字符串foo = "the"
,foo[0]
为"t"
,查找lower_case
"t"
,并将其与大写"T"
值匹配。事实上,Ruby源代码显示:
static VALUE
rb_str_capitalize_bang(VALUE str)
{
rb_encoding *enc;
char *s, *send;
int modify = 0;
unsigned int c;
int n;
str_modify_keep_cr(str);
enc = STR_ENC_GET(str);
rb_str_check_dummy_enc(enc);
if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil;
s = RSTRING_PTR(str); send = RSTRING_END(str);
c = rb_enc_codepoint_len(s, send, &n, enc);
if (rb_enc_islower(c, enc)) {
rb_enc_mbcput(rb_enc_toupper(c, enc), s, enc);
modify = 1;
}
s += n;
while (s < send) {
c = rb_enc_codepoint_len(s, send, &n, enc);
if (rb_enc_isupper(c, enc)) {
rb_enc_mbcput(rb_enc_tolower(c, enc), s, enc);
modify = 1;
}
s += n;
}
if (modify) return str;
return Qnil;
}
相关功能为toupper
。它如何知道toupper("t")
等于"T"
?
答案 0 :(得分:6)
你想知道它是如何知道角色的大写版本是什么的?像大多数此类函数的实际实现一样,它使用lookup table。
答案 1 :(得分:1)
toupper
是ansi C function。这意味着确切的实现实际上取决于库的提供程序,大多数情况下它是您的编译器。
有可能它遵循ASCII表,因为没有查找和整数之和一样快 - 查找中的一个步骤应该包含一个和,来计算新地址。
所以,on gcc,我们有这个实现
char
ctype<char>::do_toupper(char __c) const
{
int __x = __c;
return (this->is(ctype_base::lower, __c) ? (__x - 'a' + 'A') : __x);
}
这基本上会检查它是否降低。如果是,则返回较低的。否则,它会减去97然后减去65,这与减去32相同。请记住,计算机的字符和数字是相同的,只是二进制数据。然后,请注意如何使用字符代替数字以获得更好的可读性(好吧,至少对于C人来说)。
答案 2 :(得分:0)
如果不查看任何源代码,我猜想一种方法是将一个字符转换为它的字符。相应的ASCII值,从中减去32并将ASCII值转换回char。