Understanding Ruby Inside Out

K

Konstantin Ka

What makes Ruby work?

This is not a guide. It's a question. And I hope there is a Ruby crack
reading this who can answer. (Be kind. It's my first post. :)

I've been learning the basics of Ruby for a bit over a week now and
while I understand those basics I can't help but wonder how all of those
basic methods work inside ruby.

In the past I also noticed that the best way to become good at anything
is to understand every detail of it (I had an education in medicine and
if you know what molecules and cells do if you throw them together, the
function and malfunctions of organs s just basic logic)

That being said, since everything in Ruby is an Object and in one way or
another belongs to the Object-Class, I'd like to see the code of that.

I want to see what basic methods do in code form. Even Kernel methods
like ... I don't know... .sort for example.

Since Kernel is a subclass of Module and Module a subclass of Object, in
one of those 3 classes every (Kernel) method had to have been defined at
one point, right?

So, is there any way I can see the class codes... or even let the code
be printed in irb via a method? Like "print sort.code" and it prints a
string with the original code inside, that would rock. (Well obviously
it would be looking for an array to sort first so that wouldn't work but
... I hope you get what I mean)

Especially interesting woud be that since every method seems to be
defined with other methods, where did the first methods come from?

How would one define the method ".def"?

Or maybe I am thinking in an entirely wrong direction? Especially since
Class.superclass #=> Module
Module.superclass #=> Object # but
Object.class #=> Class

... which I can't wrap my head around.


These questions seem fairly basic to me, but none of the beginner guides
I found even came close to explaining this. So please point me in the
right direction.

Thank you,

-Konstantin
 
O

Oskar M. Grande

I am still relatively new to ruby myself but what helped me a lot until now w=
as David Black's "The Well Grounded Rubyist" in combination with reading th=
e MRI source code. Just another noobie's 2c.. Have a nice sunday :)=20
 
P

Phillip Gawlowski

That being said, since everything in Ruby is an Object and in one way or
another belongs to the Object-Class, I'd like to see the code of that.

You can!

Just download <http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p180.tar.gz>,
extract, and start digging through the C code.

Or grab Rubinius' source code to see Ruby implemented in Ruby. Or
JRuby to see it in Java. Or IronRuby to see it in .NET/C#.

Or grab all four to compare them side by side.
How would one define the method ".def"?

Not everything in Ruby is a method. There's keywords which are neither
objects nor methods, too. class, def, end, or if belong to this group.

These questions seem fairly basic to me, but none of the beginner guides
I found even came close to explaining this. So please point me in the
right direction.

Language implementation isn't usually a beginner's topic. ;)

But books I can recommend:
- Eloquent Ruby, by Russ Olsen
- The Ruby Programming Language, by our very own Matz.*
- Programming Ruby, 3rd Edition**

All these books dive into the how and why Ruby does things.

* based on hearsay; I haven't read the book myself. Yet.
** I own the 2nd edition of the Pickaxe which covers Ruby 1.8 and is
excellent; the 3rd edition covers Ruby 1.9 in the same depth.

--
Phillip Gawlowski

Though the folk I have met,
(Ah, how soon!) they forget
When I've moved on to some other place,
There may be one or two,
When I've played and passed through,
Who'll remember my song or my face.
 
S

Stu

What makes Ruby work?

This is not a guide. It's a question. And I hope there is a Ruby crack
reading this who can answer. (Be kind. It's my first post. :)

I've been learning the basics of Ruby for a bit over a week now and
while I understand those basics I can't help but wonder how all of those
basic methods work inside ruby.

In the past I also noticed that the best way to become good at anything
is to understand every detail of it (I had an education in medicine and
if you know what molecules and cells do if you throw them together, the
function and malfunctions of organs s just basic logic)

That being said, since everything in Ruby is an Object and in one way or
another belongs to the Object-Class, I'd like to see the code of that.

I want to see what basic methods do in code form. Even Kernel methods
like ... I don't know... .sort for example.

Since Kernel is a subclass of Module and Module a subclass of Object, in
one of those 3 classes every (Kernel) method had to have been defined at
one point, right?

So, is there any way I can see the class codes... or even let the code
be printed in irb via a method? Like "print sort.code" and it prints a
string with the original code inside, that would rock. (Well obviously
it would be looking for an array to sort first so that wouldn't work but
... I hope you get what I mean)

Especially interesting woud be that since every method seems to be
defined with other methods, where did the first methods come from?

How would one define the method ".def"?

Or maybe I am thinking in an entirely wrong direction? Especially since

... which I can't wrap my head around.


These questions seem fairly basic to me, but none of the beginner guides
I found even came close to explaining this. So please point me in the
right direction.

Thank you,

-Konstantin

Hello Konstantin

The low level sort algorithm is written in C. if you need to look at
it you will have to look at the source code. is there a specific
reason you need to see sort? I'm sure it's a qsort or bubble sort
algorithm.

To define a method .def you can within your own classes. but what I
believe your really looking for is the eval family of methods for
meta-programming which include:
=> [:eval, :module_eval, :class_eval, :instance_eval]

There is also the define_method which is cleaner and is the ruby way
of dynamically generating methods. (i.e. with a block)

define_method is a private method of the Module class=> [:define_method]

also consider how easy it is to open up a class and extend it on it's
own structure without eval:

Class String
def rand
self.split('').shuffle.join
end
alias random rand
end
=> "onet a,tKinlonlHs"

I reopened class String. created a method called rand. Since
everything in ruby is a sender and receiver I sent the string "Hello,
Konstantin" through a split() method which returns a array of chars.
Then through the shuffle() method which acts like a driver providing
the randomness to the array. then they are joined back into a string
with the join() method which then returns the now modified string to
the top level main calling object. I also used an alias to show that
shortcuts and duplication of methods can me simplified.

One thing that confuses people when they first start ruby is that
there is an implicit return for all methods. The rule is the last
expression is returned. I could have easily written
return(self.split('').shuffle.join) if I needed to be more verbose.

Another note that may help you conceptually is that everything in ruby
has a binding. When you get to variables and scope remember that as it
may help.

~Stu
 
K

Konstantin Ka

Hey, thanks for the rapid response guys.

@Oliver & Phillip Thanks for the pointer towards the source codes. (and
book recommendations are also appreciated)

I guess that answers the part where the first methods / keywords come
from to build upon in ruby. I mean I already guessed that part could
only be answered by looking at the C code of Ruby itself.

Now @Stu you seem to be onto what I was looking for with the other part
of the original question.

Even if the basic commands are embedded within the C of Ruby itself,
aren't there already pre-defined (let's call them "2nd tier") methods
based on Ruby code already within those superclasses?

Like, assume for a moment that the rand method you defined as an example
above really was an embedded function in Ruby that I didn't have to
define before I can use it. (I assume it isn't, right?)

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.


Now Stu, the part where you explained:
the eval family of methods for
meta-programming which include:
=> [:eval, :module_eval, :class_eval, :instance_eval]

There is also the define_method which is cleaner and is the ruby way
of dynamically generating methods. (i.e. with a block)

define_method is a private method of the Module class=> [:define_method]

...

I didn't understand a word of that... which probably means you are
somewhat right that I might be looking for that :)

What would .grep(/eval/) do? What is an eval family? That returned array
of symbols ... are those further methods?

Thanks,

-Konstantin
 
P

Phillip Gawlowski

Even if the basic commands are embedded within the C of Ruby itself,
aren't there already pre-defined (let's call them "2nd tier") methods
based on Ruby code already within those superclasses?

Well, the Ruby interpreter is written in whatever host language is
used (C, Java, &c.).

Ruby's methods are usually (but not nearly always) defined in Ruby
code building upon the capabilities of the interpreter.

More or less, you have to look at two different things: The Ruby
standard library, and the Ruby interpreter. How you start depends on
whether you like to go from amino acids to organs, to organisms or the
other way around.
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


... 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.

Of course. I grabbed a random example out of <www.ruby-doc.org/core/>:

http://ruby-doc.org/core/classes/File.src/M000006.html

The source for a given method right there. This is the File#atime
function, reachable from here:
http://ruby-doc.org/core/classes/File.html (BTW: I hate frames), just
click on a method name.

--=20
Phillip Gawlowski

Though the folk I have met,
(Ah, how soon!) they forget
When I've moved on to some other place,
There may be one or two,
When I've played and passed through,
Who'll remember my song or my face.
 
K

Konstantin Ka

Phillip Gawlowski wrote in post #996058:
Of course. I grabbed a random example out of <www.ruby-doc.org/core/>:

http://ruby-doc.org/core/classes/File.src/M000006.html

The source for a given method right there. This is the File#atime
function, reachable from here:
http://ruby-doc.org/core/classes/File.html (BTW: I hate frames), just
click on a method name.

Very good, I can work with that. Feeling kind of embarassed that the
answer is in the official documentation. But I swear I googled before.
Basically you could've answered me "RTFM" and you would've been right
:)

Anyway, thanks again for the help. I've got a nice amount of "bedtime
reading material" now.
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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


... 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"
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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 = 0;
9: int lim = 0;
10: VALUE result, tmp;
11:
12: if (rb_scan_args(argc, argv, "02", &spat, &limit) == 2) {
13: lim = NUM2INT(limit);
14: if (lim <= 0) limit = Qnil;
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 = 1;
21: }
22:
23: enc = STR_ENC_GET(str);
24: if (NIL_P(spat)) {
25: if (!NIL_P(rb_fs)) {
26: spat = rb_fs;
27: goto fs_set;
28: }
29: split_type = awk;
30: }
31: else {
32: fs_set:
33: if (TYPE(spat) == T_STRING) {
34: rb_encoding *enc2 = STR_ENC_GET(spat);
35:
36: split_type = string;
37: if (RSTRING_LEN(spat) == 0) {
38: /* Special case - split into chars */
39: spat = rb_reg_regcomp(spat);
40: split_type = regexp;
41: }
42: else if (rb_enc_asciicompat(enc2) == 1) {
43: if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' '){
44: split_type = awk;
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 = awk;
52: }
53: }
54: }
55: else {
56: spat = get_pat(spat, 1);
57: split_type = regexp;
58: }
59: }
60:
61: result = rb_ary_new();
62: beg = 0;
63: if (split_type == awk) {
64: char *ptr = RSTRING_PTR(str);
65: char *eptr = RSTRING_END(str);
66: char *bptr = ptr;
67: int skip = 1;
68: unsigned int c;
69:
70: end = beg;
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 = ptr - bptr;
77: }
78: else {
79: end = ptr - bptr;
80: skip = 0;
81: if (!NIL_P(limit) && lim <= i) break;
82: }
83: }
84: else if (ascii_isspace(c)) {
85: rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
86: skip = 1;
87: beg = ptr - bptr;
88: if (!NIL_P(limit)) ++i;
89: }
90: else {
91: end = ptr - bptr;
92: }
93: }
94: }
95: else {
96: while (ptr < eptr) {
97: int n;
98:
99: c = rb_enc_codepoint_len(ptr, eptr, &n, enc);
100: ptr += n;
101: if (skip) {
102: if (rb_isspace(c)) {
103: beg = ptr - bptr;
104: }
105: else {
106: end = ptr - bptr;
107: skip = 0;
108: if (!NIL_P(limit) && lim <= i) break;
109: }
110: }
111: else if (rb_isspace(c)) {
112: rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
113: skip = 1;
114: beg = ptr - bptr;
115: if (!NIL_P(limit)) ++i;
116: }
117: else {
118: end = ptr - bptr;
119: }
120: }
121: }
122: }
123: else if (split_type == string) {
124: char *ptr = RSTRING_PTR(str);
125: char *temp = ptr;
126: char *eptr = RSTRING_END(str);
127: char *sptr = RSTRING_PTR(spat);
128: long slen = RSTRING_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 = rb_enc_check(str, spat);
137: while (ptr < eptr &&
138: (end = rb_memsearch(sptr, slen, ptr, eptr - ptr, enc)) >= 0)
{
139: /* Check we are at the start of a char */
140: char *t = rb_enc_right_char_head(ptr, ptr + end, eptr, enc);
141: if (t != ptr + end) {
142: ptr = t;
143: continue;
144: }
145: rb_ary_push(result, rb_str_subseq(str, ptr - temp, end));
146: ptr += end + slen;
147: if (!NIL_P(limit) && lim <= ++i) break;
148: }
149: beg = ptr - temp;
150: }
151: else {
152: char *ptr = RSTRING_PTR(str);
153: long len = RSTRING_LEN(str);
154: long start = beg;
155: long idx;
156: int last_null = 0;
157: struct re_registers *regs;
158:
159: while ((end = rb_reg_search(spat, str, start, 0)) >= 0) {
160: regs = RMATCH_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 = start;
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 = 1;
179: continue;
180: }
181: }
182: else {
183: rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
184: beg = start = END(0);
185: }
186: last_null = 0;
187:
188: for (idx=1; idx < regs->num_regs; idx++) {
189: if (BEG(idx) == -1) continue;
190: if (BEG(idx) == END(idx))
191: tmp = str_new_empty(str);
192: else
193: tmp = rb_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 = str_new_empty(str);
202: else
203: tmp = rb_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 = RARRAY_LEN(result)) > 0 &&
209: (tmp = RARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) == 0))
210: rb_ary_pop(result);
211: }
212:
213: return result;
214: }
pry(main)> exit
 
S

Stu

Hey, thanks for the rapid response guys.

@Oliver & Phillip Thanks for the pointer towards the source codes. (and
book recommendations are also appreciated)

Yukihiro Matsumoto's book is the one you want. Everything else is just
peripheral.
I guess that answers the part where the first methods / keywords come
from to build upon in ruby. I mean I already guessed that part could
only be answered by looking at the C code of Ruby itself.

Now @Stu you seem to be onto what I was looking for with the other part
of the original question.

Even if the basic commands are embedded within the C of Ruby itself,
aren't there already pre-defined (let's call them "2nd tier") methods
based on Ruby code already within those superclasses?

In ruby version 1.9.x every object inherits from BasicObject.
BasicObject acts as a base class for everything.

Ruby doesn't really have fundamental data types. Everything is an
abstract data type which in ruby is closer to being defined as a
fundamental data structure. The abstraction becomes more obvious when
you can see the polymorphic design and method overloading in it's
classes.

For example what you may not realize is that your operators are also
methods. Ruby uses a fancy syntactic sugar to allow what looks like a
statement 1 + 3 which is really and expression 1.+(3)

+ is a method. In this case part of one of the numerical classes. It
becomes redefined for several other ruby fundamental data structures.
Example here is how + is used in ruby collections and strings. It's
just fluid to the programmer which is Matz' genius in polymorphic
object design.

[3.14, 42, 13] + [5,4,3,2,1]

"Hello, " + "Konstantin"

Looking at how the operator methods are used in collections and
strings may help you conceptually with ruby.
Like, assume for a moment that the rand method you defined as an example
above really was an embedded function in Ruby that I didn't have to
define before I can use it. (I assume it isn't, right?)

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


... 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.

There is a project called pry which allows you to cd to the object and
type ls and look at it's state. But what it sounds like your looking
for is a more computer science concept of understanding data
structures and algorithms.

understanding these concepts most definitely will allow you to become
a better programmer in general but you need to consider that ruby is a
high level language. Data structures and algorithms tend to be best
grokked on low level languages or on paper or whiteboard. Do a google
for bubble sort. Do it by hand on paper. See if you can implement it
yourself with languages that provide larger datasets like ruby and
languages that provide a bare minimum set of function like C. mind you
C is not a beginners programming language as by design it doesn't
protect the programmer from overflowing the stack. It does allow
control of mapping memory though which makes it a great language to
understand how memory works in computers.

If you do go this route you'll begin to notice some easter eggs in
ruby (i.e. Queue, Struct push, pop). The difference is that in C you'd
actually implement push and pop yourself.
Now Stu, the part where you explained:
the eval family of methods for
meta-programming which include:
=A0Kernel.methods.grep(/eval/)
=A0=3D> [:eval, :module_eval, :class_eval, :instance_eval]

There is also the define_method which is cleaner and is the ruby way
of dynamically generating methods. (i.e. with a block)

define_method is a private method of the Module class
Module.private_methods.grep(/define_m/)
=A0=3D> [:define_method]

...

I didn't understand a word of that... which probably means you are
somewhat right that I might be looking for that :)

What would .grep(/eval/) do? What is an eval family? That returned array
of symbols ... are those further methods?

Thanks,

-Konstantin

you made reference to redefining def which is possible but don't do that =
=3D)
I took that as you where interested in ruby's meta programming
facility. eval is short for evaluate expression. It's lineage comes
the UNIX command line program of the same name. I'll explain in a
second but first want to get the grep question out of the way.

grep is a search utility which also comes from the UNIX command set as
one of it's earliest programs. The UNIX philosophy initially was to
create tools that do one thing and do them well. If the program didn't
exist and couldn't be created with the set of tools already on the
system drop down to C and make a new tool. The programs would be
executed and output could stream to the input of another program via
system call known as pipe. These 'batch' scripts could be glued
together through a simple glue language called sh. sh was also the
shell and was the first to incorporate a repl and programming language
in one interface. A simple contrived example would be this

$ printf "Hello \nworld" | grep w

on the command line this would print the word 'world' because it
searched for anything that contained the letter 'w'.

Ruby allows me to grep strings and collections. ruby's object
hierarchy is exposed with the methods method which can be grepped as
so:
=3D> [:instance_methods, :public_instance_methods,
:protected_instance_methods, :private_instance_methods, :methods,
:singleton_methods, :protected_methods, :private_methods,
:public_methods]

grep's ancestor is the UNIX line editor ed. It's strange name comes
from g/re/p which is a construct in ed for global / regular expression
/ print. You can almost follow the lineage in how some programming
languages work from the history of these programs.

ed -> grep -> sed -> awk ------> perl -> ruby

Ruby borrowed many ideas from perl which was the first to break UNIX
design philosophy of many tools which could be programmed in a modular
fashion vs a monolithic tool that does everything.

Either way knowing something about the unix toolset will help you
understand many things in ruby. Ruby is a very unix-centric language.
If your interested in seeing what it's all about look at FreeBSD
(http://www.freebsd.org/)

A simple explanation on how eval works is to see the code below:

def generate_method( name)
m =3D <<EOF
def #{name}_say
puts "#{name} is grokking the Ruby Programming Language"
end
EOF
eval m
end

Here I am using a heredoc which is really just a multi-line string
with interpolation and set in the variable m. when eval runs on m a
new method is created. Look at my irb output:
stu is grokking the Ruby Programming Language
=3D> nilkonstantin is grokking the Ruby Programming Language

Though this example is overly contrived you can see where it may be
useful for generating boilerplate functionality on the fly.

Hope some of this information is useful to you.

~Stu
 
S

Stu

One last thing to try which may help you. If you pass false to
instance_methods you can get the list of methods directly associated
with that class without the inherited methods:

=> [:<=>, :==, :===, :eql?, :hash, :casecmp, :+, :*, :%, :[], :[]=,
:insert, :length, :size, :bytesize, :empty?, :=~, :match, :succ,
:succ!, :next, :next!, :upto, :index, :rindex, :replace, :clear, :chr,
:getbyte, :setbyte, :to_i, :to_f, :to_s, :to_str, :inspect, :dump,
:upcase, :downcase, :capitalize, :swapcase, :upcase!, :downcase!,
:capitalize!, :swapcase!, :hex, :eek:ct, :split, :lines, :bytes, :chars,
:codepoints, :reverse, :reverse!, :concat, :<<, :crypt, :intern,
:to_sym, :eek:rd, :include?, :start_with?, :end_with?, :scan, :ljust,
:rjust, :center, :sub, :gsub, :chop, :chomp, :strip, :lstrip, :rstrip,
:sub!, :gsub!, :chop!, :chomp!, :strip!, :lstrip!, :rstrip!, :tr,
:tr_s, :delete, :squeeze, :count, :tr!, :tr_s!, :delete!, :squeeze!,
:each_line, :each_byte, :each_char, :each_codepoint, :sum, :slice,
:slice!, :partition, :rpartition, :encoding, :force_encoding,
:valid_encoding?, :ascii_only?, :unpack, :encode, :encode!, :to_r,
:to_c]

This is all the methods associated with the top level String class.

~Stu
 
R

Robert Klemme

I've been learning the basics of Ruby for a bit over a week now and
while I understand those basics I can't help but wonder how all of those
basic methods work inside ruby.

In the past I also noticed that the best way to become good at anything
is to understand every detail of it (I had an education in medicine and
if you know what molecules and cells do if you throw them together, the
function and malfunctions of organs s just basic logic)

That is certainly not true for me; apparently we have different
learning experiences. Still, I would think that it is easier to start
with learning to _use_ the language before diving into implementation
details. The reason I am suggesting is, that otherwise you might not
see the forest for the trees: a solid understanding of Ruby as a
language (not how it is implemented) will give you a mental framework
where to plug in implementation details once you learn them.
These questions seem fairly basic to me, but none of the beginner guides
I found even came close to explaining this. So please point me in the
right direction.

That's probably because you do not need to know these in order to
learn the language - even properly so. I believe in an early stage of
adoption of the Ruby language would do more harm than good. I cannot
judge how far you have gone with understanding and using the language
but I get the feeling that you might be jumping into deep water too
early.

Kind regards

robert
 
7

7stud --

Robert K. wrote in post #996173:
I second what Robert said. Dredging up C code is not the way to
understand ruby. You should learn how to use ruby up to an
intermedidate level first, and then for the really cool stuff read
"Metaprogramming Ruby". Why things work is not at all useful. How
things work is much more important. If you just have to look at source
code, this would be the way to go:
Or grab Rubinius' source code to see Ruby implemented in Ruby.
=====

Like, assume for a moment that the rand method you defined
as an example above really was an embedded function in
Ruby that I didn't have to define before I can use it.
(I assume it isn't, right?)

Wrong. rand() is a standard ruby method that you can call (it's defined
in Kernel). rand() is a common method that is included in most
programming languages.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top