# I love Ruby

**URL:** <https://rubytalk.org/t/i-love-ruby/12480>\
**Category:** ruby-talk\
**Created:** [9 July 2004 10:17 UTC](https://rubytalk.org/t/i-love-ruby/12480 "2004-07-09T10:17:32Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Graham\_Nicholls2](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@Graham\_Nicholls2](https://rubytalk.org/u/Graham_Nicholls2)\
**Post date:** [9 July 2004 10:17 UTC](https://rubytalk.org/t/i-love-ruby/12480/1 "2004-07-09T10:17:32Z")

</div>

I had to say it! I teach for LearningTree, so was able to attend a perl  
course for free. I \_hated\_ perl - what a mess. Then I saw that python was  
"perl done properly", so looked at that. \_Much\_ better, but a few  
irritations. Then I thought "I'll try ruby". I did, but didn't have time  
to do much. Got a couple of books - both very good, although I have some  
constructive criticisms for both (Programming Ruby, & The Ruby Way), and  
now I'm an expert (not!). I love that everything's an object, so I can  
just do x.y.z.j.f combining methods - like this:

val=@data.fetch([datid.tr](http://datid.tr)('~','$').sub(/\s\*$/,'')

(I hope thats not considered bad form) So much that I intuitively try works  
- which is great.

I've not crossposted to c.l.python, as this (really) isn't a troll, but I'm  
coming to the conclusion that ruby is "python done properly". But don't  
tell anyone - I don't want to be flamed senseless.  
Anyway, antirant over, back to work.  
Graham

PS. 1 complaint - begin and end. I use vi (vim/gvim), and would prefer the  
use of braces so I can quickly go to the matching start/end block with %.  
Any suggestions? a #define equivalent, perhaps?

> **···**
>
> --  
> With Linux, the answer's always "Yes"

---

<div class="post-metadata">

**Author:** ![Laurent\_Julliard4](https://avatars.discourse-cdn.com/v4/letter/l/ebca7d/32.png) [@Laurent\_Julliard4](https://rubytalk.org/u/Laurent_Julliard4)\
**Post date:** [9 July 2004 10:52 UTC](https://rubytalk.org/t/i-love-ruby/12480/2 "2004-07-09T10:52:34Z")

</div>

> I had to say it!

you're welcome 🙂

\<snip\>

> I love that everything's an object, so I can  
> just do x.y.z.j.f combining methods - like this:
> 
> val=@data.fetch(datid.tr('~','$').sub(/\s\*$/,'')
> 
> (I hope thats not considered bad form) So much that I intuitively try works  
> - which is great.

yeah, we all love this feeling, and not, it's not considered bad form.  
Remember that you can even chain methods on the end of blocks, like:  
foo.gsub do |x|  
...  
end.gsub do |x|  
...  
end

> I've not crossposted to c.l.python, as this (really) isn't a troll, but I'm  
> coming to the conclusion that ruby is "python done properly".

usually people seem to think that ruby is smalltalk or lisp or perl  
done properly. Probably all of this are just unlambda done properly 🙂

\<snip\>

> PS. 1 complaint - begin and end. I use vi (vim/gvim), and would prefer the  
> use of braces so I can quickly go to the matching start/end block with %.  
> Any suggestions? a #define equivalent, perhaps?

I think ruby.vim allows you to do the same trick.  
Anyway, usually you don't need begin..end.

Say, in a method you don't have to write:

def foo  
begin  
&nbsp;&nbsp;bla  
rescue  
&nbsp;&nbsp;blablsa  
end  
end

you can just write:

def foo  
bla  
rescue  
blabla  
end

And this is most of the begin..end usage 🙂

> **···**
>
> il Fri, 09 Jul 2004 11:15:59 +0100, Graham Nicholls \<graham@rockcons.co.uk\> ha scritto::

---

<div class="post-metadata">

**Author:** ![zuzu](https://avatars.discourse-cdn.com/v4/letter/z/ce73a5/32.png) [@zuzu](https://rubytalk.org/u/zuzu)\
**Post date:** [9 July 2004 10:56 UTC](https://rubytalk.org/t/i-love-ruby/12480/3 "2004-07-09T10:56:47Z")

</div>

> I had to say it! I teach for LearningTree, so was able to attend a perl  
> course for free. I \_hated\_ perl - what a mess. Then I saw that python was  
> "perl done properly", so looked at that. \_Much\_ better, but a few  
> irritations. Then I thought "I'll try ruby". I did, but didn't have time  
> to do much. Got a couple of books - both very good, although I have some  
> constructive criticisms for both (Programming Ruby, & The Ruby Way), and  
> now I'm an expert (not!). I love that everything's an object, so I can  
> just do x.y.z.j.f combining methods - like this:
> 
> val=@data.fetch(datid.tr('~','$').sub(/\s\*$/,'')
> 
> (I hope thats not considered bad form) So much that I intuitively try works  
> - which is great.

grab someone else and ask them, "is it obvious which object owns these  
functions?"  
to me, this does.  
&nbsp;&nbsp;&nbsp;data --\> .fetch  
&nbsp;&nbsp;&nbsp;datid --\> .tr  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sub

but you appear to be missing a closing )  
😉

> I've not crossposted to c.l.python, as this (really) isn't a troll, but I'm  
> coming to the conclusion that ruby is "python done properly". But don't  
> tell anyone - I don't want to be flamed senseless.  
> Anyway, antirant over, back to work.  
> Graham

i've been gushing about ruby lately too, and i went through a similar  
experience.  
first i tried perl because so many sysadmin and early web cgi  
programmers were raving about it, but TMTOWTDI made reverse-engineer  
learning perl from cpan rather evil. (i had to learn that perl is  
meant to be written, not read.) then i became thoroughly frustrated  
with C++ and python looked like "interpreted C++ with none of the  
mess", but the underscores bothered me more than tabbed delimiting.  
then i looked into the history of programming languages, lisp, and why  
alan kay invented smalltalk. then i remember hearing about ruby and  
let go of "great... an even more niche language". now i feel smarter  
when programming instead of dumber, as i did with C++. a near-perfect  
blend of perl, lisp, and smalltalk (+eiffel, so people say). ruby  
makes me happy.

> PS. 1 complaint - begin and end. I use vi (vim/gvim), and would prefer the  
> use of braces so I can quickly go to the matching start/end block with %.  
> Any suggestions? a #define equivalent, perhaps?

i agree with your one complaint. maybe because C++ was the first  
serious language i learned, maybe because { } looks more symmetrical  
to me and take ~1/4 the number of keystrokes to input.

why are 'begin...end' and { } not always equivalent?

> --  
> With Linux, the answer's always "Yes"

with a "but..."

-z

> **···**
>
> On Fri, 9 Jul 2004 19:17:32 +0900, Graham Nicholls \<graham@rockcons.co.uk\> wrote:

---

<div class="post-metadata">

**Author:** ![ChokSheak\_Lau](https://avatars.discourse-cdn.com/v4/letter/c/8e8cbc/32.png) [@ChokSheak\_Lau](https://rubytalk.org/u/ChokSheak_Lau)\
**Post date:** [9 July 2004 12:57 UTC](https://rubytalk.org/t/i-love-ruby/12480/4 "2004-07-09T12:57:32Z")

</div>

"Graham Nicholls" \<graham@rockcons.co.uk\> wrote in message  
news:40ee705f$0$11817$afc38c87@auth.uk.news.easynet.net...

> PS. 1 complaint - begin and end. I use vi (vim/gvim), and would prefer the  
> use of braces so I can quickly go to the matching start/end block with %.  
> Any suggestions? a #define equivalent, perhaps?

hi Graham, I think that's a good point. I personally feel that using {}  
makes it easier  
for the eye to match a block. maybe Ruby can include this alternate syntax  
in the parser?

chok

---

<div class="post-metadata">

**Author:** ![Kaspar\_Schiess](https://avatars.discourse-cdn.com/v4/letter/k/d78d45/32.png) [@Kaspar\_Schiess](https://rubytalk.org/u/Kaspar_Schiess)\
**Post date:** [9 July 2004 11:28 UTC](https://rubytalk.org/t/i-love-ruby/12480/5 "2004-07-09T11:28:41Z")

</div>

> why are 'begin...end' and { } not always equivalent?

This comes up once in a while, tell me if this answer is short enough:

def foo(arg=nil)  
&nbsp;&nbsp;if block\_given?  
&nbsp;&nbsp;&nbsp;&nbsp;puts 'foo got block'  
&nbsp;&nbsp;end  
end

def bar(arg=nil)  
&nbsp;&nbsp;if block\_given?  
&nbsp;&nbsp;&nbsp;&nbsp;puts 'bar got block'  
&nbsp;&nbsp;end  
end

foo bar do end # \> foo got block  
foo bar {} # \> bar got block

best regards,  
kaspar

semantics & semiotics  
code manufacture

www.tua.ch/ruby

---

<div class="post-metadata">

**Author:** ![Kristof\_Bastiaensen1](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kristof\_Bastiaensen1](https://rubytalk.org/u/Kristof_Bastiaensen1)\
**Post date:** [9 July 2004 12:02 UTC](https://rubytalk.org/t/i-love-ruby/12480/6 "2004-07-09T12:02:45Z")

</div>

FYI, I have written a unlambda interpreter in Ruby. (I don't know  
if I should be proud of it...) It was ridiculously easy, because  
Ruby already provides everything (continuations, closures,...). I think  
the implementation is even easier to understand than the spec.  
It is not a very efficient implementation, since it uses recursion.  
But you don't have very large unlambda programs that you absolutely  
need to run, do you?

Here it is:  
(Don't continue reading if you don't want to waste your time...)

#!/usr/bin/env ruby

#Unlambda interpreter  
#written by Kristof Bastiaensen \<kristof.bastiaensen@vleeuwen.org\>

require "stringio"

def readchar  
&nbsp;&nbsp;$char\_read = getc  
end

K = lambda {|a| lambda { |b| a }}  
S = lambda {|a| lambda { |b| lambda { |c| a[c][b[c]] }}}  
I = lambda { |a| a }  
V = lambda { |a| V }  
R = lambda { |a| puts; a }  
C = lambda { |a| callcc { |cc| a[cc] } }  
D = lambda { |a| a}  
AT = lambda { |a| (readchar() ? a : V ) }  
PIPE = lambda { |a| $char\_read ? a[$char\_read] : V }

CharLookup = { ?k =\> K, ?s =\> S, ?i =\> I,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?v =\> V, ?r =\> R, ?c =\> C,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?@ =\> AT, ?| =\> PIPE,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?d =\> D, ?e =\> :dummy }

def compile(stream)  
&nbsp;&nbsp;loop do  
&nbsp;&nbsp;&nbsp;&nbsp;raise "Premature end of stream!" if stream.eof  
&nbsp;&nbsp;&nbsp;&nbsp;ch = stream.getc  
&nbsp;&nbsp;&nbsp;&nbsp;if ch == ?` #`  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return [compile(stream), compile(stream)]  
&nbsp;&nbsp;&nbsp;&nbsp;elsif ch == ?.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = stream.getc  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return lambda { |b| print a.chr; b }  
&nbsp;&nbsp;&nbsp;&nbsp;elsif ch == ??  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = stream.getc  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return lambda { |b| b == a ? a : V }  
&nbsp;&nbsp;&nbsp;&nbsp;elsif CharLookup.member?(ch)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return CharLookup[ch]  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

def eval\_expr(expr)  
&nbsp;&nbsp;if expr.class == Array  
&nbsp;&nbsp;&nbsp;&nbsp;r = eval\_expr(expr[0])  
&nbsp;&nbsp;&nbsp;&nbsp;e2 = expr[1]  
&nbsp;&nbsp;&nbsp;&nbsp;if (r == D and e2.class == Array)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return lambda { |a| eval\_expr(e2)[a] }  
&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return r[eval\_expr(e2)]  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;return expr  
&nbsp;&nbsp;end  
end

def eval(string)  
&nbsp;&nbsp;string = string.gsub(/#.\*$/, "")  
&nbsp;&nbsp;stream = StringIO.new(string, "r")  
&nbsp;&nbsp;callcc do |exit|  
&nbsp;&nbsp;&nbsp;&nbsp;CharLookup[?e] = lambda { |a| exit[a] }  
&nbsp;&nbsp;&nbsp;&nbsp;tree = compile(stream)  
&nbsp;&nbsp;&nbsp;&nbsp;eval\_expr(tree)  
&nbsp;&nbsp;end  
end

if(ARGV.length != 1)  
&nbsp;&nbsp;$stderr \<\< "Usage: %s \<unlambda file\>\n" % $0  
else  
&nbsp;&nbsp;str = IO.read(ARGV[0])  
&nbsp;&nbsp;eval(str)  
end

> **···**
>
> On Fri, 09 Jul 2004 10:52:17 +0000, gabriele renzi wrote:
> 
> > usually people seem to think that ruby is smalltalk or lisp or perl  
> > done properly. Probably all of this are just unlambda done properly 🙂

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [9 July 2004 13:24 UTC](https://rubytalk.org/t/i-love-ruby/12480/7 "2004-07-09T13:24:14Z")

</div>

Hi --

> **···**
>
> On Fri, 9 Jul 2004, ChokSheak Lau wrote:
> 
> > "Graham Nicholls" \<graham@rockcons.co.uk\> wrote in message  
> > news:40ee705f$0$11817$afc38c87@auth.uk.news.easynet.net...  
> > \> PS. 1 complaint - begin and end. I use vi (vim/gvim), and would prefer the  
> > \> use of braces so I can quickly go to the matching start/end block with %.  
> > \> Any suggestions? a #define equivalent, perhaps?
> > 
> > hi Graham, I think that's a good point. I personally feel that using {}  
> > makes it easier  
> > for the eye to match a block. maybe Ruby can include this alternate syntax  
> > in the parser?
> 
> I don't think there would be any way to distinguish this from a hash  
> literal.
> 
> David
> 
> --  
> David A. Black  
> dblack@wobblini.net

---

<div class="post-metadata">

**Author:** ![Graham\_Nicholls2](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@Graham\_Nicholls2](https://rubytalk.org/u/Graham_Nicholls2)\
**Post date:** [9 July 2004 14:32 UTC](https://rubytalk.org/t/i-love-ruby/12480/8 "2004-07-09T14:32:36Z")

</div>

zuzu wrote:

> but you appear to be missing a closing )  
> 😉

I noticed about 2 minutes after I posted, when I tried to run it, which was  
really annoying!  
G.

> **···**
>
> --  
> With Linux, the answer's always "Yes"

---

<div class="post-metadata">

**Author:** ![Graham\_Nicholls2](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@Graham\_Nicholls2](https://rubytalk.org/u/Graham_Nicholls2)\
**Post date:** [9 July 2004 11:52 UTC](https://rubytalk.org/t/i-love-ruby/12480/9 "2004-07-09T11:52:30Z")

</div>

Kaspar Schiess wrote:

> -----BEGIN PGP SIGNED MESSAGE-----  
> Hash: SHA1
> 
> \> why are 'begin...end' and { } not always equivalent?  
> This comes up once in a while, tell me if this answer is short enough:

I didn't even know there was a {} !  
Documentation (up to date) would seem to be a minor problem with ruby - am I  
being reasonable ? (To be fair, I've yet to read my 2 books from cover to  
cover, so I've probably missed it.) For instance, I believe theres no 1.8  
documentation. I'm still in love, though 😉

> **···**
>
> --  
> With Linux, the answer's always "Yes"

---

<div class="post-metadata">

**Author:** ![zuzu](https://avatars.discourse-cdn.com/v4/letter/z/ce73a5/32.png) [@zuzu](https://rubytalk.org/u/zuzu)\
**Post date:** [9 July 2004 11:58 UTC](https://rubytalk.org/t/i-love-ruby/12480/10 "2004-07-09T11:58:23Z")

</div>

> -----BEGIN PGP SIGNED MESSAGE-----  
> Hash: SHA1
> 
> \> why are 'begin...end' and { } not always equivalent?  
> This comes up once in a while, tell me if this answer is short enough:
> 
> def foo(arg=nil)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_given?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'foo got block'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> end
> 
> def bar(arg=nil)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block\_given?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'bar got block'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> end
> 
> foo bar do end # \> foo got block  
> foo bar {} # \> bar got block
> 
> best regards,  
> kaspar

why the difference in scope?  
why does 'do...end' pass into foo instead of bar?

p.s. "foo bar" feels quite ambiguous without any defining ( ).

> semantics & semiotics

\<topic bool="off"\>  
ever look at "general semantics" by alfred korzybski?  
do you have any opinion on fred dretske w/r/t semiotics?  
\</topic\>

> **···**
>
> On Fri, 9 Jul 2004 20:28:41 +0900, Kaspar Schiess \<eule@space.ch\> wrote:
> 
> > code manufacture
> > 
> > www.tua.ch/ruby  
> > -----BEGIN PGP SIGNATURE-----  
> > Version: GnuPG v1.2.4 (MingW32)  
> > Comment: Using GnuPG with Thunderbird - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)
> > 
> > iD8DBQFA7oKYFifl4CA0ImQRAn/NAKCH39gW0a58Uw/Y3eiNnxStOPVRtACgmNRF  
> > Mpz4p0OGorKJ3ic+Wyje150=  
> > =XIcv  
> > -----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![Laurent\_Julliard4](https://avatars.discourse-cdn.com/v4/letter/l/ebca7d/32.png) [@Laurent\_Julliard4](https://rubytalk.org/u/Laurent_Julliard4)\
**Post date:** [9 July 2004 13:27 UTC](https://rubytalk.org/t/i-love-ruby/12480/11 "2004-07-09T13:27:32Z")

</div>

:)))  
I wa thinking to write an unlambda interpreter just after my exams'  
session , end of july 😉

Damn, now I have to write the COW one..  
givent that brainf\*\*k and OOk! are already there maybe we should start  
a section on the wiki 🙂

> **···**
>
> il Fri, 09 Jul 2004 14:02:46 +0200, Kristof Bastiaensen \<kristof@vleeuwen.org\> ha scritto::
> 
> > On Fri, 09 Jul 2004 10:52:17 +0000, gabriele renzi wrote:
> > 
> > > usually people seem to think that ruby is smalltalk or lisp or perl  
> > > done properly. Probably all of this are just unlambda done properly 🙂
> > 
> > FYI, I have written a unlambda interpreter in Ruby. (I don't know  
> > if I should be proud of it...) It was ridiculously easy, because  
> > Ruby already provides everything (continuations, closures,...). I think  
> > the implementation is even easier to understand than the spec.  
> > It is not a very efficient implementation, since it uses recursion.  
> > But you don't have very large unlambda programs that you absolutely  
> > need to run, do you?

---

<div class="post-metadata">

**Author:** ![Michael\_Geary](https://avatars.discourse-cdn.com/v4/letter/m/2acd7d/32.png) [@Michael\_Geary](https://rubytalk.org/u/Michael_Geary)\
**Post date:** [9 July 2004 16:47 UTC](https://rubytalk.org/t/i-love-ruby/12480/12 "2004-07-09T16:47:31Z")

</div>

> \> why are 'begin...end' and { } not always equivalent?

Kaspar Schiess wrote:

> This comes up once in a while, tell me if this answer is short enough:  
> [indentation added]
> 
> def foo(arg=nil)  
> &nbsp;&nbsp;&nbsp;&nbsp;if block\_given?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'foo got block'  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> end
> 
> def bar(arg=nil)  
> &nbsp;&nbsp;&nbsp;&nbsp;if block\_given?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'bar got block'  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> end
> 
> foo bar do end # \> foo got block  
> foo bar {} # \> bar got block

That is very helpful, thanks.

One thing I don't understand: \*Why\* does it work this way? What is the  
purpose of having different precedence for {} and do...end? It's always  
seemed a bit confusing to me, so knowing the purpose for this distinction  
would help keep it straight.

Thanks,

-Mike

---

<div class="post-metadata">

**Author:** ![Laurent\_Julliard4](https://avatars.discourse-cdn.com/v4/letter/l/ebca7d/32.png) [@Laurent\_Julliard4](https://rubytalk.org/u/Laurent_Julliard4)\
**Post date:** [9 July 2004 12:02 UTC](https://rubytalk.org/t/i-love-ruby/12480/13 "2004-07-09T12:02:32Z")

</div>

you're reasonable but not in this thing.  
blocks in ruby are in the form:

amethod do |vars|  
body  
end

or

amethod { |vars|  
body  
}

this is the only place where {} are used as syntax delimiters, and the  
common idiom is to use do..end for multiline stuff, and {..} for  
one-line blocks.

You can't use them in place of begin..end, like:

begin  
print 10  
end while true

{  
print 10  
} while true

> **···**
>
> il Fri, 09 Jul 2004 12:51:27 +0100, Graham Nicholls \<graham@rockcons.co.uk\> ha scritto::
> 
> > I didn't even know there was a {} !  
> > Documentation (up to date) would seem to be a minor problem with ruby - am I  
> > being reasonable ? (To be fair, I've yet to read my 2 books from cover to  
> > cover, so I've probably missed it.) For instance, I believe theres no 1.8  
> > documentation. I'm still in love, though 😉

---

<div class="post-metadata">

**Author:** ![Kaspar\_Schiess](https://avatars.discourse-cdn.com/v4/letter/k/d78d45/32.png) [@Kaspar\_Schiess](https://rubytalk.org/u/Kaspar_Schiess)\
**Post date:** [9 July 2004 12:15 UTC](https://rubytalk.org/t/i-love-ruby/12480/14 "2004-07-09T12:15:52Z")

</div>

zuzu wrote:

> > why the difference in scope?  
> > why does 'do...end' pass into foo instead of bar?

Actually the difference is one of 'operator precedence' and not one of  
scope, as far as {} can be called an operator. {} just binds very thight  
to the call to bar, whereas do end binds loosely to the call of foo.  
This means that

~ puts str.gsub { ... }

will do what you expected but

~ puts str.gsub do ... end

will call puts with a block. Hence the single line/multiline difference.

Thank you for your OT (not to me) pointers, I will put them on the list  
of things to  
read ! Perhaps you will be interested in my opinion afterwards 😉 ?

yours,  
kaspar

semantics & semiotics  
code manufacture

www.tua.ch/ruby

---

<div class="post-metadata">

**Author:** ![Kristof\_Bastiaensen1](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kristof\_Bastiaensen1](https://rubytalk.org/u/Kristof_Bastiaensen1)\
**Post date:** [9 July 2004 14:12 UTC](https://rubytalk.org/t/i-love-ruby/12480/15 "2004-07-09T14:12:42Z")

</div>

> :)))  
> I wa thinking to write an unlambda interpreter just after my exams'  
> session , end of july 😉

Yes, I thought it would be a real challenge, but it appeared to  
be very easy in the end. Everything is already in the language.  
Now a ruby interpreter in unlambda, that would be a challenge!

> Damn, now I have to write the COW one..  
> givent that brainf\*\*k and OOk! are already there maybe we should start  
> a section on the wiki 🙂

Yes, the "Ruby Comprehensive Esoteric language Archive",  
why not?

Kristof

> **···**
>
> On Fri, 09 Jul 2004 13:24:11 +0000, gabriele renzi wrote:

---

<div class="post-metadata">

**Author:** ![Florian\_Gross](https://avatars.discourse-cdn.com/v4/letter/f/e9a140/32.png) [@Florian\_Gross](https://rubytalk.org/u/Florian_Gross)\
**Post date:** [9 July 2004 19:27 UTC](https://rubytalk.org/t/i-love-ruby/12480/16 "2004-07-09T19:27:31Z")

</div>

gabriele renzi wrote:

> Damn, now I have to write the COW one.. givent that brainf\*\*k and OOk! are already there maybe we should start  
> a section on the wiki 🙂

Now I just \*have\* to post my Brainfuck interpreter where all instructions can dynamically be changed and new ones can be added without problems:

> **···**
>
> > begin  
> > &nbsp;&nbsp;require 'simplecc'  
> > rescue LoadError  
> > &nbsp;&nbsp;def Continuation.create(\*args, &block)  
> > &nbsp;&nbsp;&nbsp;&nbsp;cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}  
> > &nbsp;&nbsp;&nbsp;&nbsp;result ||= args  
> > &nbsp;&nbsp;&nbsp;&nbsp;return \*[cc, \*result]  
> > &nbsp;&nbsp;end  
> > end
> > 
> > class BrainfuckContext  
> > &nbsp;&nbsp;def initialize(code = nil, instructions = {})  
> > &nbsp;&nbsp;&nbsp;&nbsp;@data, @pointer, @jumps = Hash.new { 0 }, 0,   
> > &nbsp;&nbsp;&nbsp;&nbsp;@instructions = Instructions.merge(instructions)  
> > &nbsp;&nbsp;&nbsp;&nbsp;execute code if code  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def execute(code)  
> > &nbsp;&nbsp;&nbsp;&nbsp;code.split(//).each do |instruction|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval(&@instructions[instruction])  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def getc; STDIN.getc || 0; end
> > 
> > &nbsp;&nbsp;Instructions = Hash.new { proc {} }.update({  
> > &nbsp;&nbsp;&nbsp;&nbsp;'\>' =\> proc { @pointer += 1 },  
> > &nbsp;&nbsp;&nbsp;&nbsp;'\<' =\> proc { @pointer -= 1 },  
> > &nbsp;&nbsp;&nbsp;&nbsp;'+' =\> proc { @data[@pointer] += 1 },  
> > &nbsp;&nbsp;&nbsp;&nbsp;'-' =\> proc { @data[@pointer] -= 1 },  
> > &nbsp;&nbsp;&nbsp;&nbsp;'.' =\> proc { putc @data[@pointer] },  
> > &nbsp;&nbsp;&nbsp;&nbsp;',' =\> proc { @data[@pointer] = getc },  
> > &nbsp;&nbsp;&nbsp;&nbsp;'[' =\> proc do  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump, jumped = Continuation.create(false)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@jumps \<\< jump  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless jumped  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@depth ||= 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@depth += 1  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# make all instructions but ']' noops  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@old\_instructions = @instructions.dup  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new\_instructions = {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'[' =\> proc { @depth += 1 },  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;']' =\> proc do  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@depth = [0, @depth - 1].max  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @depth == 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# restore standard instruction table  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@instructions.update(@old\_instructions) if @old\_instructions  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@old\_instructions = nil  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump = @jumps.pop  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump.call(true) if jump and @data[@pointer] != 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@instructions = @old\_instructions.dup.clear.update(new\_instructions)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;end,  
> > &nbsp;&nbsp;&nbsp;&nbsp;']' =\> proc do  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump = @jumps.pop  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump.call(true) if jump and @data[@pointer] != 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;end,  
> > &nbsp;&nbsp;&nbsp;&nbsp;'#' =\> proc do  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = @data.to\_a.sort\_by { |(key, value)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}.map { |(key, value)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"#{key} = #{value}"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}.join(", ")  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "#{@pointer} @ [#{data}]"  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;})  
> > end
> > 
> > def bf(code)  
> > &nbsp;&nbsp;BrainfuckContext.new(code)  
> > end

---

<div class="post-metadata">

**Author:** ![zuzu](https://avatars.discourse-cdn.com/v4/letter/z/ce73a5/32.png) [@zuzu](https://rubytalk.org/u/zuzu)\
**Post date:** [9 July 2004 12:12 UTC](https://rubytalk.org/t/i-love-ruby/12480/17 "2004-07-09T12:12:58Z")

</div>

> \>I didn't even know there was a {} !  
> \>Documentation (up to date) would seem to be a minor problem with ruby - am I  
> \>being reasonable ? (To be fair, I've yet to read my 2 books from cover to  
> \>cover, so I've probably missed it.) For instance, I believe theres no 1.8  
> \>documentation. I'm still in love, though 😉

[http://www.rubycentral.com/book/](http://www.rubycentral.com/book/)

it feels a bit like "v1.0" documentation and tends to be a bit too  
"for tradtional programmers" as a bridge to the ruby way of thinking  
for my tastes. (i'd rather be explained the "accepted style" upfront,  
personally.) but it is by far one of the best books on howto  
programming, let alone learning ruby, i've read.

some where in there it explains about begin...end, then iirc talks  
about blocks, then explains about { }. i would lump that together,  
personally, but that's the "v1.0" thing. p.s. the "pragmatic  
programmers" are pretty on the ball about improving the process of  
programming; their other book is worth reading as well.

> **···**
>
> On Fri, 9 Jul 2004 21:02:32 +0900, gabriele renzi \<surrender\_it@rc1.vip.ukl.yahoo.com\> wrote:
> 
> > il Fri, 09 Jul 2004 12:51:27 +0100, Graham Nicholls \> \<graham@rockcons.co.uk\> ha scritto::
> 
> > you're reasonable but not in this thing.  
> > blocks in ruby are in the form:
> > 
> > amethod do |vars|  
> > body  
> > end
> > 
> > or
> > 
> > amethod { |vars|  
> > body  
> > }
> > 
> > this is the only place where {} are used as syntax delimiters, and the  
> > common idiom is to use do..end for multiline stuff, and {..} for  
> > one-line blocks.
> > 
> > You can't use them in place of begin..end, like:
> > 
> > begin  
> > print 10  
> > end while true
> > 
> > {  
> > print 10  
> > } while true

---

<div class="post-metadata">

**Author:** ![zuzu](https://avatars.discourse-cdn.com/v4/letter/z/ce73a5/32.png) [@zuzu](https://rubytalk.org/u/zuzu)\
**Post date:** [9 July 2004 12:30 UTC](https://rubytalk.org/t/i-love-ruby/12480/18 "2004-07-09T12:30:24Z")

</div>

> -----BEGIN PGP SIGNED MESSAGE-----  
> Hash: SHA1
> 
> zuzu wrote:
> 
> \>\> why the difference in scope?  
> \>\> why does 'do...end' pass into foo instead of bar?
> 
> Actually the difference is one of 'operator precedence' and not one of  
> scope, as far as {} can be called an operator. {} just binds very thight  
> to the call to bar, whereas do end binds loosely to the call of foo.  
> This means that
> 
> ~ puts str.gsub { ... }
> 
> will do what you expected but
> 
> ~ puts str.gsub do ... end
> 
> will call puts with a block. Hence the single line/multiline difference.

\*lightbulb\* word.

..."that's not intuitive!" 😉

i would think that if you want to pass 'puts' a block, you should have  
to more strongly define:  
puts(str.gsub) do ... end

lots of words with spaces weirds me out, like applescript.

> Thank you for your OT (not to me) pointers, I will put them on the list  
> of things to  
> read ! Perhaps you will be interested in my opinion afterwards 😉 ?

certainly. especially if you can finish 'science & sanity' by korzybski.  
dretske i'm so-so on, but supposidly 'flow of information' is the  
leading treatise on applying information theory to language... i  
think his research is solid, but so far disagree with his conclusion  
that knowledge is "all or nothing"; obviously he hasn't learned null-A  
from korzybski.

> **···**
>
> On Fri, 9 Jul 2004 21:15:52 +0900, Kaspar Schiess \<eule@space.ch\> wrote:
> 
> > yours,  
> > kaspar
> > 
> > semantics & semiotics  
> > code manufacture
> > 
> > www.tua.ch/ruby  
> > -----BEGIN PGP SIGNATURE-----  
> > Version: GnuPG v1.2.4 (MingW32)  
> > Comment: Using GnuPG with Thunderbird - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)
> > 
> > iD8DBQFA7o2oFifl4CA0ImQRAsDzAKCzLCTMaE/f9lvJ3dvWXoSjeDltxgCfewzT  
> > dLMLTUzKpxUlwBhIsMvTREQ=  
> > =mY7c  
> > -----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![Graham\_Nicholls2](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@Graham\_Nicholls2](https://rubytalk.org/u/Graham_Nicholls2)\
**Post date:** [9 July 2004 12:57 UTC](https://rubytalk.org/t/i-love-ruby/12480/19 "2004-07-09T12:57:31Z")

</div>

gabriele renzi wrote:

> this is the only place where {} are used as syntax delimiters, and the  
> common idiom is to use do..end for multiline stuff, and {..} for  
> one-line blocks.

Ah, of course I had seen this.

> You can't use them in place of begin..end, like:
> 
> begin  
> print 10  
> end while true

This is what I thought was being said. Thanks for clearing that up!  
(Shame, though)  
Graham

> **···**
>
> --  
> With Linux, the answer's always "Yes"
