--20cf3071cfae466a6204a23b8ef6
Content-Type: text/plain; charset=ISO-8859-1

On Sun, May 1, 2011 at 1:56 PM, Josh Cheek <josh.cheek / gmail.com> wrote:

> On Sun, May 1, 2011 at 4:29 AM, Konstantin Ka <paranox3 / yahoo.de> wrote:
>
>>
>> Would there be any way that Ruby-Newbie-mme could come along, have a
>> look inside the preprogrammed String class and see written there in Ruby
>> language
>>
>> >  def rand
>> >    self.split('').shuffle.join
>> >  end
>>
>> ... because that would enable me to go "Oh, sure! It splits the string,
>> shuffles it, and joins it back together. Sounds easy!" even if, to find
>> out what some of those "1st tier" methods like .split actually do, I'd
>> have to go look at the C code.
>>
>>
>>
> Check out the gem pry (get it by going to the command line and typing "gem
> install pry pry-doc" -- possibly requiring "sudo" privelages, and possibly
> not working on 1.8.6)
>
> Then you can start a pry session with "pry"
>

Sorry I hit space or something, and it sent the message before I finished.
Here is an example session. Pry is a repl (like irb) but it knows how to do
lots of really useful things. One of these is reflecting upon code. In this
case, I tell it to show me the documentation for String#split, then I tell
it to show me the code for String#split For more cool things you can do with
it, check out
http://rdoc.info/github/banister/pry/master/file/README.markdown


$ pry -f


pry(main)> show-doc String#split

From: string.c in Ruby Core (C Method):
Number of lines: 36

Divides str into substrings based on a delimiter, returning an array
of these substrings.

If pattern is a String, then its contents are used as
the delimiter when splitting str. If pattern is a single
space, str is split on whitespace, with leading whitespace and runs
of contiguous whitespace characters ignored.

If pattern is a Regexp, str is divided where the
pattern matches. Whenever the pattern matches a zero-length string,
str is split into individual characters. If pattern contains
groups, the respective matches will be returned in the array as well.

If pattern is omitted, the value of $; is used.  If
$; is nil (which is the default), str is
split on whitespace as if ` ' were specified.

If the limit parameter is omitted, trailing null fields are
suppressed. If limit is a positive number, at most that number of
fields will be returned (if limit is 1, the entire
string is returned as the only entry in an array). If negative, there is no
limit to the number of fields returned, and trailing null fields are not
suppressed.

   " now's  the time".split        #["now's", "the", "time"]
   " now's  the time".split(' ')   #["now's", "the", "time"]
   " now's  the time".split(/ /)   #["", "now's", "", "the", "time"]
   "1, 2.34,56, 7".split(%r{,\s*}) #["1", "2.34", "56", "7"]
   "hello".split(//)               #["h", "e", "l", "l", "o"]
   "hello".split(//, 3)            #["h", "e", "llo"]
   "hi mom".split(%r{\s*})         #["h", "i", "m", "o", "m"]

   "mellow yellow".split("ello")   #["m", "w y", "w"]
   "1,2,,3,4,,".split(',')         #["1", "2", "", "3", "4"]
   "1,2,,3,4,,".split(',', 4)      #["1", "2", "", "3,4,,"]
   "1,2,,3,4,,".split(',', -4)     #["1", "2", "", "3", "4", "", ""]


pry(main)> show-method -l -f String#split

From: string.c in Ruby Core (C Method):
Number of lines: 214

1: static VALUE
2: rb_str_split_m(int argc, VALUE *argv, VALUE str)
3: {
4:     rb_encoding *enc;
5:     VALUE spat;
6:     VALUE limit;
7:     enum {awk, string, regexp} split_type;
8:     long beg, end, i  ;
9:     int lim  ;
10:     VALUE result, tmp;
11:
12:     if (rb_scan_args(argc, argv, "02", &spat, &limit) 2) {
13:     lim  UM2INT(limit);
14:     if (lim < ) limit  nil;
15:     else if (lim 1) {
16:         if (RSTRING_LEN(str) 0)
17:         return rb_ary_new2(0);
18:         return rb_ary_new3(1, str);
19:     }
20:     i  ;
21:     }
22:
23:     enc  TR_ENC_GET(str);
24:     if (NIL_P(spat)) {
25:     if (!NIL_P(rb_fs)) {
26:         spat  b_fs;
27:         goto fs_set;
28:     }
29:     split_type  wk;
30:     }
31:     else {
32:       fs_set:
33:     if (TYPE(spat) T_STRING) {
34:         rb_encoding *enc2  TR_ENC_GET(spat);
35:
36:         split_type  tring;
37:         if (RSTRING_LEN(spat) 0) {
38:         /* Special case - split into chars */
39:         spat  b_reg_regcomp(spat);
40:         split_type  egexp;
41:         }
42:         else if (rb_enc_asciicompat(enc2) 1) {
43:         if (RSTRING_LEN(spat) 1 && RSTRING_PTR(spat)[0] ' '){
44:             split_type  wk;
45:         }
46:         }
47:         else {
48:         int l;
49:         if (rb_enc_ascget(RSTRING_PTR(spat), RSTRING_END(spat), &l,
enc2) ' ' &&
50:             RSTRING_LEN(spat) l) {
51:             split_type  wk;
52:         }
53:         }
54:     }
55:     else {
56:         spat  et_pat(spat, 1);
57:         split_type  egexp;
58:     }
59:     }
60:
61:     result  b_ary_new();
62:     beg  ;
63:     if (split_type awk) {
64:     char *ptr  STRING_PTR(str);
65:     char *eptr  STRING_END(str);
66:     char *bptr  tr;
67:     int skip  ;
68:     unsigned int c;
69:
70:     end  eg;
71:     if (is_ascii_string(str)) {
72:         while (ptr < eptr) {
73:         c  unsigned char)*ptr++;
74:         if (skip) {
75:             if (ascii_isspace(c)) {
76:             beg  tr - bptr;
77:             }
78:             else {
79:             end  tr - bptr;
80:             skip  ;
81:             if (!NIL_P(limit) && lim < ) break;
82:             }
83:         }
84:         else if (ascii_isspace(c)) {
85:             rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
86:             skip  ;
87:             beg  tr - bptr;
88:             if (!NIL_P(limit)) ++i;
89:         }
90:         else {
91:             end  tr - bptr;
92:         }
93:         }
94:     }
95:     else {
96:         while (ptr < eptr) {
97:         int n;
98:
99:         c  b_enc_codepoint_len(ptr, eptr, &n, enc);
100:         ptr + ;
101:         if (skip) {
102:             if (rb_isspace(c)) {
103:             beg  tr - bptr;
104:             }
105:             else {
106:             end  tr - bptr;
107:             skip  ;
108:             if (!NIL_P(limit) && lim < ) break;
109:             }
110:         }
111:         else if (rb_isspace(c)) {
112:             rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
113:             skip  ;
114:             beg  tr - bptr;
115:             if (!NIL_P(limit)) ++i;
116:         }
117:         else {
118:             end  tr - bptr;
119:         }
120:         }
121:     }
122:     }
123:     else if (split_type string) {
124:     char *ptr  STRING_PTR(str);
125:     char *temp  tr;
126:     char *eptr  STRING_END(str);
127:     char *sptr  STRING_PTR(spat);
128:     long slen  STRING_LEN(spat);
129:
130:     if (is_broken_string(str)) {
131:         rb_raise(rb_eArgError, "invalid byte sequence in %s",
rb_enc_name(STR_ENC_GET(str)));
132:     }
133:     if (is_broken_string(spat)) {
134:         rb_raise(rb_eArgError, "invalid byte sequence in %s",
rb_enc_name(STR_ENC_GET(spat)));
135:     }
136:     enc  b_enc_check(str, spat);
137:     while (ptr < eptr &&
138:            (end  b_memsearch(sptr, slen, ptr, eptr - ptr, enc)) > )
{
139:         /* Check we are at the start of a char */
140:         char *t  b_enc_right_char_head(ptr, ptr + end, eptr, enc);
141:         if (t ! tr + end) {
142:         ptr  ;
143:         continue;
144:         }
145:         rb_ary_push(result, rb_str_subseq(str, ptr - temp, end));
146:         ptr + nd + slen;
147:         if (!NIL_P(limit) && lim < +i) break;
148:     }
149:     beg  tr - temp;
150:     }
151:     else {
152:     char *ptr  STRING_PTR(str);
153:     long len  STRING_LEN(str);
154:     long start  eg;
155:     long idx;
156:     int last_null  ;
157:     struct re_registers *regs;
158:
159:     while ((end  b_reg_search(spat, str, start, 0)) > ) {
160:         regs  MATCH_REGS(rb_backref_get());
161:         if (start end && BEG(0) END(0)) {
162:         if (!ptr) {
163:             rb_ary_push(result, str_new_empty(str));
164:             break;
165:         }
166:         else if (last_null 1) {
167:             rb_ary_push(result, rb_str_subseq(str, beg,
168:                               rb_enc_fast_mbclen(ptr+beg,
169:                                      ptr+len,
170:                                      enc)));
171:             beg  tart;
172:         }
173:         else {
174:                     if (ptr+start ptr+len)
175:                         start++;
176:                     else
177:                         start +rb_enc_fast_mbclen(ptr+start,ptr+len,enc);
178:             last_null  ;
179:             continue;
180:         }
181:         }
182:         else {
183:         rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
184:         beg  tart  ND(0);
185:         }
186:         last_null  ;
187:
188:         for (idx idx < regs->num_regs; idx++) {
189:         if (BEG(idx) -1) continue;
190:         if (BEG(idx) END(idx))
191:             tmp  tr_new_empty(str);
192:         else
193:             tmp  b_str_subseq(str, BEG(idx), END(idx)-BEG(idx));
194:         rb_ary_push(result, tmp);
195:         }
196:         if (!NIL_P(limit) && lim < +i) break;
197:     }
198:     }
199:     if (RSTRING_LEN(str) > 0 && (!NIL_P(limit) || RSTRING_LEN(str) >
beg || lim < 0)) {
200:     if (RSTRING_LEN(str) beg)
201:         tmp  tr_new_empty(str);
202:     else
203:         tmp  b_str_subseq(str, beg, RSTRING_LEN(str)-beg);
204:     rb_ary_push(result, tmp);
205:     }
206:     if (NIL_P(limit) && lim 0) {
207:     long len;
208:     while ((len  ARRAY_LEN(result)) > 0 &&
209:            (tmp  ARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) 0))
210:         rb_ary_pop(result);
211:     }
212:
213:     return result;
214: }
pry(main)> exit

--20cf3071cfae466a6204a23b8ef6--