[MacRuby-devel] Weird behaviour for a weird line of code

42 views
Skip to first unread message

Mark Rada

unread,
Nov 14, 2010, 9:37:47 PM11/14/10
to macrub...@lists.macosforge.org
Hey,

I wrote a line of code that I thought was correct (but maybe not so pretty) and in one case it was giving me a weird error. I was wondering if someone could explain to me what is wrong with it; I suspect there is some behaviour of MacRuby that I am not understanding. Here are a few examples that are close to what I had:

A working case: (Case #1)

require 'uri'
test = URI.parse url unless (url = nil).nil? # works, as I expected, url is nil and the left side is not evaluated


Ok, try again, but without a nil value for url: (Case #2)

require 'uri'
test = URI.parse url unless (url = 'http://macruby.org/').nil? # error about url not being defined


Now, when I try this out in macirb: (Case #3)

require 'uri'
test = URI.parse url unless (url = 'http://macruby.org/').nil? # error again

test = URI.parse url unless (url = 'http://wikipedia.org/').nil? # works fine this time

puts test.to_s # gives me the wikipedia value


If it doesn't work in the second case, why does it start working in the third case?

Thanks,
Mark

_______________________________________________
MacRuby-devel mailing list
MacRub...@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Leigh Caplan

unread,
Nov 15, 2010, 12:29:50 AM11/15/10
to MacRuby development discussions.
I had digest mode turned on, so this reply might be orphaned. Sorry in advance if that's the case.

Thanks Matt for showing me your HTTP wrapper... there are some good ideas there.

In reply to Josh, what would be the advantages of using NSURLConnection as the transport for the net/* libraries? I can see that having access to two different built-in mechanisms for dealing with the network may be confusing; I used NSURLConnection as an example, but there are many facets of Cocoa which don't have corresponding support in Ruby, and that's where I see a great opportunity for a wrapper library. I just find it way easier to reason about my code if async callbacks are defined inline using procs and the like.

I can also see disadvantages to this approach, such as extra indirection whilst debugging, and potential for more memory usage if the implementers (read: me) aren't careful about making sure that stored procs eventually go out of scope.

Additionally, it probably wouldn't make sense to wrap everything in all the frameworks– we could probably identify logical groups of classes where having more Ruby-like conventions would be a good fit. I'll go over Foundation.framework in the next week and see if I can do just that.

Leigh

Ryan Davis

unread,
Nov 15, 2010, 4:50:49 PM11/15/10
to MacRuby development discussions.

On Nov 14, 2010, at 18:37 , Mark Rada wrote:

> Now, when I try this out in macirb: (Case #3)
>
> require 'uri'
> test = URI.parse url unless (url = 'http://macruby.org/').nil? # error

> test = URI.parse url unless (url = 'http://wikipedia.org/').nil? # works
>

> If it doesn't work in the second case, why does it start working in the third case?

First off, I hate this style of coding. If you didn't assign in a conditional you'd avoid all of this crap to begin with. Assigning in conditionals is just a sloppy and error prone way of coding and you should avoid it. This has been a known anti-pattern in any algol-esque language since at least the 80s.

That said... This actually has nothing to do with macruby and is an effect of the ruby parser. It is about variable visibility.

In case 3:

+ The first line has "URI.parse url" followed by "unless (url = ...).nil?"
+ The first 'url' is actually parsed as a method call because the word has never been seen before and wasn't added to the variable table. The second url DOES add url to the variable table.
+ The second line has the same thing, but by now, "url" has been added to the variable table. This lets everything be parsed as a variable at parse time.

Here is how you should code it:

> require 'uri'
> url = "http://macruby.org/"
> test = URI.parse url if url
> url = "http://wikipedia.org/"
> test = URI.parse url if url

no variable parse ambiguity. no testing for nil specifically (.nil? is almost NEVER needed, just test for truthiness--imagine what happens when someone sets url to false with your code). clean. readable.

Your code all it's nerdiness:

s(:block,
s(:if, s(:call, s(:lasgn, :url, s(:str, "http://macruby.org/")),
:nil?, s(:arglist)),
nil,
s(:lasgn, :test,
s(:call, s(:const, :URI), :parse,
s(:arglist, s(:call, nil, :url, s(:arglist)))))), # HERE IT IS A CALL
s(:if,
s(:call, s(:lasgn, :url, s(:str, "http://wikipedia.org/")), :nil?,
s(:arglist)),
nil,
s(:lasgn, :test,
s(:call, s(:const, :URI), :parse, s(:arglist, s(:lvar, :url))))))

Mark Rada

unread,
Nov 16, 2010, 12:25:06 AM11/16/10
to MacRuby development discussions.

On 2010-11-15, at 4:50 PM, Ryan Davis wrote:

>
> On Nov 14, 2010, at 18:37 , Mark Rada wrote:
>
>> Now, when I try this out in macirb: (Case #3)
>>
>> require 'uri'
>> test = URI.parse url unless (url = 'http://macruby.org/').nil? # error
>> test = URI.parse url unless (url = 'http://wikipedia.org/').nil? # works
>>
>> If it doesn't work in the second case, why does it start working in the third case?
>
> First off, I hate this style of coding. If you didn't assign in a conditional you'd avoid all of this crap to begin with. Assigning in conditionals is just a sloppy and error prone way of coding and you should avoid it. This has been a known anti-pattern in any algol-esque language since at least the 80s.
>
> That said... This actually has nothing to do with macruby and is an effect of the ruby parser. It is about variable visibility.

Ah, that is what I was not understanding. Thanks for explaining.

>
> In case 3:
>
> + The first line has "URI.parse url" followed by "unless (url = ...).nil?"
> + The first 'url' is actually parsed as a method call because the word has never been seen before and wasn't added to the variable table. The second url DOES add url to the variable table.
> + The second line has the same thing, but by now, "url" has been added to the variable table. This lets everything be parsed as a variable at parse time.

Eric Christopherson

unread,
Nov 16, 2010, 5:14:56 PM11/16/10
to MacRuby development discussions.
On Mon, Nov 15, 2010 at 3:50 PM, Ryan Davis <ryand...@zenspider.com> wrote:
>
> On Nov 14, 2010, at 18:37 , Mark Rada wrote:
>
>> Now, when I try this out in macirb: (Case #3)
>>
>>   require 'uri'
>>   test = URI.parse url unless (url = 'http://macruby.org/').nil?  # error
>>   test = URI.parse url unless (url = 'http://wikipedia.org/').nil? # works
>>
>> If it doesn't work in the second case, why does it start working in the third case?
>
> First off, I hate this style of coding. If you didn't assign in a conditional you'd avoid all of this crap to begin with. Assigning in conditionals is just a sloppy and error prone way of coding and you should avoid it. This has been a known anti-pattern in any algol-esque language since at least the 80s.

I'm not sure I understand what you mean. Are you saying it's bad to do
the *first* assignment to a variable inside a conditional? Or it's bad
to assign inside a conditional in any case? I can understand the
first, but I'm not sure how you would work around the second, unless
you used a more functional style like

x = (n > 2 ? true : false)

or

x = (if n > 2; true; else false; end)

Jeff Cohen

unread,
Nov 16, 2010, 5:55:22 PM11/16/10
to MacRuby development discussions.
On Tue, Nov 16, 2010 at 4:14 PM, Eric Christopherson <echrist...@gmail.com> wrote:
On Mon, Nov 15, 2010 at 3:50 PM, Ryan Davis <ryand...@zenspider.com> wrote:
> First off, I hate this style of coding. If you didn't assign in a conditional you'd avoid all of this crap to begin with. Assigning in conditionals is just a sloppy and error prone way of coding and you should avoid it. This has been a known anti-pattern in any algol-esque language since at least the 80s.

I'm not sure I understand what you mean. Are you saying it's bad to do
the *first* assignment to a variable inside a conditional? Or it's bad
to assign inside a conditional in any case?

It's bad to assign inside a condition in any case.  
 
I can understand the
first, but I'm not sure how you would work around the second, unless
you used a more functional style like

x = (n > 2 ? true : false)

or

x = (if n > 2; true; else false; end)

Um... just do:

x = n > 2
 

Jeff

Ryan Davis

unread,
Nov 16, 2010, 6:22:06 PM11/16/10
to MacRuby development discussions.

On Nov 16, 2010, at 14:14 , Eric Christopherson wrote:

> I'm not sure I understand what you mean. Are you saying it's bad to do
> the *first* assignment to a variable inside a conditional? Or it's bad
> to assign inside a conditional in any case? I can understand the
> first, but I'm not sure how you would work around the second, unless
> you used a more functional style like
>
> x = (n > 2 ? true : false)
>
> or
>
> x = (if n > 2; true; else false; end)

this is not an assignment inside a conditional. It is a conditional inside an assignment. And as Jeff pointed out, while just an example, it is a very contrived example (that hits one of my biggest pet peeves).

an assignment inside a conditional is

do_something(x) if x = logical_statement

or

if x = logical_statement then
do_something(x)
else
do_something_else
end

and whether you're coding in ruby, C/++, or whatever... it is almost always considered bad form. Avoid it not only for the reasons I mentioned before, but also to avoid the beat downs you'll get whenever you ask for our community's help. I cannot guarantee your safety otherwise.

Caio Chassot

unread,
Nov 16, 2010, 7:20:36 PM11/16/10
to MacRuby development discussions.
On 2010-11-16, at 21:22 , Ryan Davis wrote:
>
> an assignment inside a conditional is
>
> do_something(x) if x = logical_statement

I'm particularly fond of:

x = logical_statement and do_something(x)

Hate me now.

Eloy Duran

unread,
Nov 18, 2010, 5:02:35 AM11/18/10
to MacRuby development discussions.
> if x = logical_statement then
> do_something(x)
> else
> do_something_else
> end
>
> and whether you're coding in ruby, C/++, or whatever... it is almost always considered bad form. Avoid it not only for the reasons I mentioned before, but also to avoid the beat downs you'll get whenever you ask for our community's help. I cannot guarantee your safety otherwise.

I see no problem with this, as long as you know what you’re doing (which is with almost anything). Nor have I witnessed a community where ‘beat downs’ are acceptable, it’s certainly not this ML. YMMV.

Scott Ribe

unread,
Nov 18, 2010, 9:48:03 AM11/18/10
to MacRuby development discussions.
On Nov 18, 2010, at 3:02 AM, Eloy Duran wrote:

> I see no problem with this, as long as you know what you’re doing (which is with almost anything). Nor have I witnessed a community where ‘beat downs’ are acceptable, it’s certainly not this ML. YMMV.

While "beat down" is clearly an exaggeration, the assignment inside condition form is certainly strongly discourage in many communities, because it's so easy to type by accident, and sometimes surprisingly hard to notice ;-)

--
Scott Ribe
scott...@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice

Eloy Duran

unread,
Nov 18, 2010, 11:01:00 AM11/18/10
to MacRuby development discussions.
I don’t want to discuss this at length, but “clearly an exaggeration” is not necessarily true. This is an international mailing-list, i.e. not all native English speakers. As such it's better to refrain from it and instead use clear language such as your “strongly discouraged, because…”. To me it was clear that those specific words were an exaggeration, but there definitely was some judgement being passed in name of ‘our community’, something which I am not happy to have on this list.

The gist of it is: anyone should be able to ask any type of question and they should not have any fear doing so. Something that newbies can have a hard time with.

Cheers,
Eloy

Matt Aimonetti

unread,
Nov 18, 2010, 11:19:50 AM11/18/10
to MacRuby development discussions.
Alright chill out people, there is no need for a drama thread.

For people who don't know Ryan Davis, Ryan is a well known personality of the Ruby community.
He's a great engineer recognized for his talent and contributions to the community. However, he is also known to be very passionate about what he believes in and could be sometimes seen as having a little problem with the form and the content ;)

In this case, I do agree with Ryan about the content and I think that his arguments are right. The final argument being that even if you disagree, you will find others who strongly believe that this kind of syntax is wrong and you might find yourself in long arguments with passionate people.
Programming isn't yet a religion, so feel free to disagree and hate Ryan as much as you want. The point being that now you know that some people see assigning values in conditionals as major programming sin & hopefully you understand their view point.

Let's not get lost in the semantic and/or the potentially trolling form ;)

Back to hacking and learning!

- Matt

Eloy Duran

unread,
Nov 18, 2010, 11:52:15 AM11/18/10
to MacRuby development discussions.
You’re right, thanks :) Back to hacking and learning!

Mario Steele

unread,
Nov 19, 2010, 4:41:10 AM11/19/10
to MacRuby development discussions.
Wait....

You mean, Programming isn't a Religion?  Seems to me, I'm always sacrificing to the Coding Goddess for working code, no matter the language. lol

Just to lighten the mood, and in agreement, Hack and Slash those bits!

Mario
--
Mario Steele
Lieutenant Commander 3
XO - Geo 99
XO - STO IFT Fleet
http://www.trekfederation.com
Reply all
Reply to author
Forward
0 new messages