Continuation...
So,
"12\^ abc23 44".scan(/\d+/)
"12\^ abc23 44".scan(/\d+/).map { |e| e }
"12\^ abc23 44".enum_for(:scan, /\d+/).map { |e| e }
"12\^ abc23 44".enum_for(:scan, /\d+/).map.to_a
"12\^ abc23 44".enum_for(:scan, /\d+/).enum_for(:map).to_a
... are pretty equivalent (in results term) and you should use the
first form,
Thanks for your details explanation.
apart from
"learning" and understanding enumerators.
Your catch is correct, Just to understand and learning.
It seems I am not able to clear myself to you people. I know how #scan works.
But question is while I am writing
"any string".enum_for(:scan, /\d+/) --- then which version of block is
actually called, *block version* or *without block* version. Because I am not
able to see it,
If I write "any string".scan(/\d+/) --- It is clear that I am using without
block version.
Now If I write "any string".scan(/\d+/) { |m| p m } - It is clear I am using
block version.
Now, while I write - "any string".enum_for(:scan, /\d+/) -- I can't see how
$scan is actually working. So my question came out right there...
Hope it is clear now.
One way I have started to understand how Ruby's interpreter works is to look at the source. These days I use pry to look at things in Ruby as I can use pry's $ command to see source:
[1]pry(main)> $ String#scan
Owner: String
Visibility: public
Number of lines: 30
static VALUE
rb_str_scan(VALUE str, VALUE pat)
{
VALUE result;
long start = 0;
long last = -1, prev = 0;
char *p = RSTRING_PTR(str); long len = RSTRING_LEN(str);
pat = get_pat(pat, 1);
if (!rb_block_given_p()) {
VALUE ary = rb_ary_new();
while (!NIL_P(result = scan_once(str, pat, &start))) {
last = prev;
prev = start;
rb_ary_push(ary, result);
}
if (last >= 0) rb_reg_search(pat, str, last, 0);
return ary;
}
while (!NIL_P(result = scan_once(str, pat, &start))) {
last = prev;
prev = start;
rb_yield(result);
str_mod_check(str, p, len);
}
if (last >= 0) rb_reg_search(pat, str, last, 0);
return str;
}
There aren't two different versions of String#scan, when a String is sent the scan message the scan method checks to see if it was given a block. If no block was given then it builds and returns a new array, populates it and returns it. If there was a block given then it yields the results as it finds them and eventually returns the original string.
Another fun place to look for implementations of bits of Ruby is in Rubinius, as most of it is written in Ruby.
Hope this helps,
Mike
···
On Jul 6, 2014, at 7:27 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:
On Sunday, July 06, 2014 08:41:34 AM Abinoam Jr. wrote:
From: string.c (C Method):
--
Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/
The "`Stok' disclaimers" apply.