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
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
> 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))))))
>
> 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.
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)
On Mon, Nov 15, 2010 at 3:50 PM, Ryan Davis <ryand...@zenspider.com> wrote:I'm not sure I understand what you mean. Are you saying it's bad to do
> 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.
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)
> 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.
I'm particularly fond of:
x = logical_statement and do_something(x)
Hate me now.
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.
> 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
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