# Readable and provocative & daring

**URL:** <https://www.ruby-forum.com/t/readable-and-provocative-daring/96628>\
**Category:** Ruby\
**Created:** [January 24, 2006, 5:03pm UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628 "2006-01-24T17:03:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![runrunshaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@runrunshaw](https://www.ruby-forum.com/u/runrunshaw)\
**Post date:** [January 24, 2006, 5:03pm UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628/1 "2006-01-24T17:03:54Z")

</div>

A funny thing happened to me in irb this week. Well, to be honest it’s  
a reconstruction. And it was little more than one thing. But hopefully  
you’ll get the gist.

irb(main):001:0\> readable = false  
=\> false  
irb(main):002:0\> readable and provocative & daring  
=\> false  
irb(main):003:0\> readable = nil  
=\> nil  
irb(main):004:0\> readable and provocative & daring  
=\> nil  
irb(main):005:0\> readable = “yes”  
=\> “yes”  
irb(main):006:0\> readable and provocative & daring  
NameError: undefined local variable or method `provocative' for main:Object from (irb):6 irb(main):007:0> provocative = false => false irb(main):008:0> readable and provocative & daring NameError: undefined local variable or method`daring’ for main:Object  
from (irb):8

Fine so far. & is eager, it always seeks to evaluate its right hand  
side. Fair cop. Let’s move on.

irb(main):009:0\> daring = nil  
=\> nil  
irb(main):010:0\> readable and provocative & daring  
=\> false  
irb(main):011:0\> provocative = nil  
=\> nil  
irb(main):012:0\> readable and provocative & daring  
=\> false

Hmm, a slightly surprising difference with and there. But does it  
matter? It didn’t to me at the time. I was Ruby newbie with an  
important business problem to solve …

irb(main):013:0\> provocative = "yes "  
=\> "yes "  
irb(main):014:0\> readable and provocative & daring  
NoMethodError: undefined method `&’ for "yes ":String  
from (irb):14

Aha. So I defined a little method in String and then …

irb(main):020:0\> readable and provocative & daring  
=\> nil  
irb(main):021:0\> daring = “please”  
=\> “please”  
irb(main):022:0\> readable and provocative & daring  
=\> “yes please”

Yep, that’s it. Now let’s really take this thing out for a spin:

irb(main):023:0\> daring = [1000, " times ", “yes”]  
=\> [1000, " times ", “yes”]  
irb(main):024:0\> readable and provocative & daring  
=\> “yes 1000 times yes”  
irb(main):025:0\> provocative = [“please”, “say”, “yes”]  
=\> [“please”, “say”, “yes”]  
irb(main):026:0\> readable and provocative & daring  
=\> [“yes”]

Hmm.

The elided code was of course

class String  
def & a  
self + a.to\_s if a  
end  
end

This was I stress again to solve a real world problem. Or, to be more  
precise, to make an existing solution to a real world problem more  
readable.

But it did feel a bit provocative and daring.

Any comments?

Richard

* * *

Ruby for laser purity

---

<div class="post-metadata">

**Author:** ![runrunshaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@runrunshaw](https://www.ruby-forum.com/u/runrunshaw)\
**Post date:** [January 24, 2006, 9:53pm UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628/2 "2006-01-24T21:53:14Z")

</div>

Some interesting stuff there…but I think the main thing is that ‘and’  
is a Ruby keyword, whereas ‘&’ is an instance method. ‘&’ can be defined  
as makes sense for whatever object it is being called on. Therefore,  
something like

> readable and provocative & daring

is equivalent to

> readable and provocative.&(daring)

which means if readable is false, then provocative.& doesn’t need to be  
called at all. However, if readable is true, then it does something like

> provocative.send(:&, daring)

If provocative doesn’t exist, it can’t call any methods on it. If  
provocative does exist, but daring doesn’t, then daring cannot be  
evaluated and can’t be passed in as a parameter to the function call.

However, once provocative and daring are defined, it can try to call the  
provocative.& method, if it exists. And since you define it, all is  
good!

My apologies if you already realized all that! The way you have the  
syntax and the fact that “and” and “&” are equivalent in English could  
be confusing…

-Justin

---

<div class="post-metadata">

**Author:** ![runrunshaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@runrunshaw](https://www.ruby-forum.com/u/runrunshaw)\
**Post date:** [January 25, 2006, 7:55am UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628/3 "2006-01-25T07:55:31Z")

</div>

> My apologies if you already realized all that!

I did kinda realise all that, except I wasn’t focusing on the fact that  
‘and’ is a keyword. Is it only with keywords that the rhs of the  
operator may not be evaluated? I don’t think so - && and || have this  
property. But I guess they cannot ever be redefined, right?

I had small questions and BIG questions here.

My BIG questions have to do with what seemed at the time a daring  
extension of the meaning of ‘&’. Is such an extension sensible: -

1. just for my project, with four other Rubyists of differing vintages?  
(I won’t tell you what they’ve said so far, that could spoil the fun!)

2. if we were to release some of our work as open source to the whole  
wide wonderful world of Ruby programmers?

I was starting with a reasonably complex conditional method that used  
‘+’ on strings that may be nil. I soon came to realise that

a + b

works fine when they’re both bona fide strings but gives an error when  
either is nil. On the other hand

nil & b

is already defined as false, which seems operationally equivalent to  
nil in every way so is exactly what I want. (Another of my small  
questions, in passing. Are nil and false ever different in their  
behavior?)

Extending ‘&’ as I have - and the opening up of a core class and method  
definition is so short and simple, I do love Ruby for that - we now  
also have

"hello " & “cheeky” -\> “hello cheeky”  
"hello " & nil -\> nil

What’s great about this is the amount of brackets and branching it  
removes from the original method.

What’s weird about it is this.

12 & 7 -\> 4

[3, 6, 9] & [2, 4, 6] -\> [6]

In other words, ‘&’ always reduces, the result is always \<= in some  
reasonable sense both arguments.

Until now.

But I still think that, in the highly pragmatic spirit of Ruby,  
everyone should have such a useful meaning for ‘&’ on Strings. I surely  
does not harm and fits in brilliantly with the much used

blob || “not known”

and

blob ||= “starter for ten”

idioms.

But I’m a newb!

Thanks very much for the feedback.

Richard

---

<div class="post-metadata">

**Author:** ![runrunshaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@runrunshaw](https://www.ruby-forum.com/u/runrunshaw)\
**Post date:** [January 25, 2006, 4:38pm UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628/4 "2006-01-25T16:38:25Z")

</div>

&& and ‘and’ both exhibit the same behaviour, in that they  
short-circuit.

& is a combiner-and, not logical (rather, typically bitwise), which  
requires it evaluate both sides of the expression.

Maybe you really wanted: readable and provocative && daring

Yes, of course, you can make your own versions, but you need to keep  
this behaviour in mind.

def foo  
p “foo”  
false  
end

foo && foo

> “foo”

foo || foo

> “foo”  
> “foo”

foo & foo

> “foo”  
> “foo”

foo and foo

---

<div class="post-metadata">

**Author:** ![runrunshaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@runrunshaw](https://www.ruby-forum.com/u/runrunshaw)\
**Post date:** [January 25, 2006, 4:59pm UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628/5 "2006-01-25T16:59:50Z")

</div>

> Yes, of course, you can make your own versions, but you need to keep  
> this behaviour in mind.

Sorry, should have realized that you can make your own version of &  
but not of &&.

---

<div class="post-metadata">

**Author:** ![runrunshaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@runrunshaw](https://www.ruby-forum.com/u/runrunshaw)\
**Post date:** [January 25, 2006, 10:08pm UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628/6 "2006-01-25T22:08:45Z")

</div>

> Sorry, should have realized that you can make your own version  
> of & but not of &&.

Yes, and it was the ability to extend & to String that started as a  
‘what if?’ this time last week and ended with some serious questions  
about how wide the utility of this version may be. Or perhaps Ruby  
veterans would vote it down for reasons I might not currently grasp?

Richard

* * *

Ruby for laser purity

---

<div class="post-metadata">

**Author:** ![runrunshaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5ac83/32.png) [@runrunshaw](https://www.ruby-forum.com/u/runrunshaw)\
**Post date:** [January 25, 2006, 10:26pm UTC](https://www.ruby-forum.com/t/readable-and-provocative-daring/96628/7 "2006-01-25T22:26:54Z")

</div>

On 1/25/06, Richard D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Yes, and it was the ability to extend & to String that started as a  
> ‘what if?’ this time last week and ended with some serious questions  
> about how wide the utility of this version may be. Or perhaps Ruby  
> veterans would vote it down for reasons I might not currently grasp?

Well, if you simply wanted to create a & method on String, that’s easy:

class String  
def &(rhs)  
self + rhs  
end  
end

If what you actually wanted is to make ‘&’ short-circuit, that’s a  
whole 'nother problem that, IMO, is best left alone. First, it flies  
in the face of the traditional meaning from other long-lived  
programming languages. (I’m very willing to discard or change  
tradition if it makes gains on efficiency, readability, etc… but I  
highly disagree that making ‘&’ short-circuit is worth it, especially  
when Ruby has both ‘&&’ and ‘and’.)

Second, it could not be (simply) implemented with a standard method  
call. The nature of calling a function is that its arguments are  
evaluated. Which means that ‘rhs’ in String.& above must be evaluated  
before the function can be called. So String.& cannot possibly  
short-circuit. (Related… If you read any good-programming-practices  
book for C++, they warn against overloading operator&& and operator||  
for specifically this reason: they cannot short-circuit.)

You could, possibly, redefine String.& like this:

class String  
def &(rhs)  
some\_cond ? self + rhs : self  
end  
end

And then, if rhs is an object that lazily evaluates, you might be able  
to fake short-circuitness. But I think it’s not worth it that much…  
smells bad, probably better ways to do things.
