# Conventions in ruby and the principle of least surprise

**URL:** <https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706>\
**Category:** Ruby\
**Created:** [January 27, 2009, 3:14am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706 "2009-01-27T03:14:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 27, 2009, 3:14am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/1 "2009-01-27T03:14:00Z")

</div>

Hi guys, and hi Matz. I have a few questions about ruby syntax and  
library that so far has had me surprised. I know Matz doesn’t say that  
ruby shouldn’t surprise me, but rather not surprise him but still, i  
would like to hear the reasoning behind a few weird things:

do…end vs. {}

Say I have this function:

def save\_block name, &b  
@blocks ||= {}  
@blocks[name] = b  
end

Now this is fine:

save\_block :say\_hello do  
puts “hello!”  
end

but not this:

save\_block :say\_hello {  
puts “hello!”  
}

I find that rather annoying but I guess it’s to be able to write things  
like

save\_block [“name1\_long”, “name2\_long”, “short”].find {|n| n.size \<=  
5}.to\_sym do  
puts “hello!”  
end

Personally I would rather have had to use parentheses to bind the block  
to find, but I realize that it’s hardly up to me 🙂

Anyways. More serious, in my oppinion, is the fact that Array#insert and  
String#insert are destructive without having an exclamation mark. Why is  
that? I really do not expect them to change their owner.

> > hi = “hello world”  
> > =\> “hello world”
> 
> > puts hi  
> > hello world  
> > =\> nil
> 
> > puts hi.insert(6, "surprising ")  
> > hello surprising world  
> > =\> nil
> 
> > puts hi  
> > hello surprising world  
> > =\> nil

seriously, wtf? Why not `insert` and `insert!` that behave as expected?  
Before I realized this I had a hard time tracking down some unexpected  
behaviour.

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 27, 2009, 3:50am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/2 "2009-01-27T03:50:12Z")

</div>

Hi,

In message “Re: Conventions in ruby and the principle of least surprise”  
on Tue, 27 Jan 2009 11:11:55 +0900, Einar Boson  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|do…end vs. {}

|I find that rather annoying but I guess it’s to be able to write things  
|like  
|  
|save\_block [“name1\_long”, “name2\_long”, “short”].find {|n| n.size \<=  
|5}.to\_sym do  
| puts “hello!”  
|end

Correct.

|Anyways. More serious, in my oppinion, is the fact that Array#insert and  
|String#insert are destructive without having an exclamation mark. Why is  
|that? I really do not expect them to change their owner.

|seriously, wtf? Why not `insert` and `insert!` that behave as expected?

The bang (!) does not mean “destructive” nor lack of it mean non  
destructive either. The bang sign means “the bang version is more  
dangerous than its non bang counterpart; handle with care”. Since  
Ruby has a lot of “destructive” methods, if bang signs follow your  
opinion, every Ruby program would be full of bangs, thus ugly.

```
          matz.

```

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 27, 2009, 9:28am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/3 "2009-01-27T09:28:09Z")

</div>

Einar Boson wrote:

> Now this is fine:
> 
> save\_block :say\_hello do  
> puts “hello!”  
> end
> 
> but not this:
> 
> save\_block :say\_hello {  
> puts “hello!”  
> }

Although this is fine:

save\_block(:say\_hello) {  
puts “hello!”  
}

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 27, 2009, 10:15pm UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/4 "2009-01-27T22:15:14Z")

</div>

On Jan 27, 2009, at 02:08 , Damjan R. wrote:

> My convention is use {} in oneliners. In all other examples I use  
> do…end.

I follow (and teach) the weirich method:

[http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc](http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc)

{} for block values I care about (think map), do/end for regular block  
sends (think each).

I use {} for blocks that return values (think #map) and do/end for all  
other blocks (think #each).

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 27, 2009, 11:10am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/5 "2009-01-27T11:10:22Z")

</div>

My convention is use {} in oneliners. In all other examples I use  
do…end.

by  
TheR

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 29, 2009, 12:40am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/6 "2009-01-29T00:40:35Z")

</div>

Mike G. wrote:

> Also, I like one rule better than two rules.

Curiously, Ruby departs with 40 years of Structural Programming  
tradition - the  
statement groups controlled by if-end, and their ilk, do _not_ introduce  
a new  
variable scope, while the statement groups inside true blocks _do_  
introduce  
scoped variables.

Furtherless, the region inside a block _might_ be someone else’s scope!  
Rails’s  
render :update do … end does this to us. Principle of Most Surprise  
applies.

So making dangerous things like blocks look ugly is a good way to help  
us  
respect them!

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 28, 2009, 1:23am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/7 "2009-01-28T01:23:46Z")

</div>

Ryan D. wrote:

> On Jan 27, 2009, at 02:08 , Damjan R. wrote:
> 
> > My convention is use {} in oneliners. In all other examples I use  
> > do…end.
> 
> I follow (and teach) the weirich method:
> 
> [http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc](http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc)
> 
> {} for block values I care about (think map), do/end for regular block  
> sends (think each).
> 
> I use {} for blocks that return values (think #map) and do/end for all  
> other blocks (think #each).

funcs = []  
(1…5).each do |i|  
funcs \<\< lambda { i }  
end  
p funcs.map { |f| f.call } # =\> [1, 2, 3, 4, 5]

funcs2 = []  
for j in 1…5  
funcs2 \<\< lambda { j }  
end  
p funcs2.map { |f| f.call } # =\> [5, 5, 5, 5, 5]

I prefer to make the new binding scope of a block visually obvious,  
therefore I always use {}. do/end tricks me into thinking it belongs to  
the same category as for/end or while/end or if/end, but it’s quite  
different (above).

Also, I like one rule better than two rules.

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [February 2, 2009, 5:45pm UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/8 "2009-02-02T17:45:22Z")

</div>

On Tue, Jan 27, 2009 at 4:12 PM, Ryan D.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> {} for block values I care about (think map), do/end for regular block  
> sends (think each).
> 
> I use {} for blocks that return values (think #map) and do/end for all  
> other blocks (think #each).

Yes, it’s the "I care about’ that matters, a subtle distinction to the  
weirich method, which I wrote about:

[http://talklikeaduck.denhaven2.com/articles/2007/10/02/ruby-blocks-do-or-brace](http://talklikeaduck.denhaven2.com/articles/2007/10/02/ruby-blocks-do-or-brace)

and Jim agreed in the comments.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)

---

<div class="post-metadata">

**Author:** ![einarmagnus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/3d9bf3/32.png) [@einarmagnus](https://www.ruby-forum.com/u/einarmagnus)\
**Post date:** [January 31, 2009, 12:35am UTC](https://www.ruby-forum.com/t/conventions-in-ruby-and-the-principle-of-least-surprise/158706/9 "2009-01-31T00:35:24Z")

</div>

Awesome 🙂 perhaps these little gems of what certain things mean as a  
FAQ could make their way into the web site.

Sent from my iPhone

On 27/01/2009, at 1:47 PM, Yukihiro M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
