6 ms·
As a Pythonista I have no idea what the Ruby snippet is doing. Readability depends entirely on context. Oh, come on. You're just disagreeing for effect here.
by aerique 17y ago
As a Pythonista I have no idea what the Ruby snippet is doing. Readability depends entirely on context.
Oh, come on. You're just disagreeing for effect here.
I've never used Ruby but that snippet is clear as day.
The Python 3 snippet suggests to me that the output would be "/hi" though :)
- rbanffy 17y ago> Oh, come on. You're just disagreeing for effect here. It's unclear what "get" is. Is it a function? What does it return? My guess would be that it returns a function bound to the handler of a "/hi" url, but that's a guess.
- steveklabnik 17y ago"get" is a function that takes a string and a block. And the block is bound to the uri given in the string, so your guess is correct.
- rbanffy 17y agoRuby always confuses me with this flexible syntax...
- steveklabnik 17y agoIt's possible that you just haven't read enough ruby, then. There are only two variations on the syntax of passing a block to a function, "do/end" and "{ }". By convention, multiline blocks use do/end, and single line blocks use {}. It's also possible that one of the things in the article is the gotcha, flexible parenthesis. By convention, Rubyists tend to use parenthesis when defining functions, but not when calling them: def get(path, opts={}, &block) get "/hello" do not get("hello") do Which would still work, if you preferred. The exception to this is chaining method calls: Users.find_all_by_age(23).select {|user| user.first_name == "steve" } ... not that that's an awesome use of ActiveRecord, but whatever.
- Confusion 17y agoOh, come on. You're just disagreeing for effect here. I've never used Ruby but that snippet is clear as day. The hell it is. I find it quite confusing. I'll take the Python 2 solution anyday, which clearly seperates what is called from when it is called. One of the main problems with the 'my language is so flexible' approach is that inventing concise solutions becomes a goal in itself.
- steveklabnik 17y ago> which clearly seperates what is called from when it is called You're passing some code as an argument to a function. Many other languages do this. Do you hate Lisp and Haskell, too? Do you not use continuations in Python? Or callback functions?
- Confusion 17y agoIf you pass a function as an argument to a function, you're still separating what from when: the function declaration shows what; the invocation of the function shows when. It doesn't matter whether it's def foo(f): f() or (define (foo f) (f)) That has nothing to do with annotating a function to show it binds to some URL and is invoked when an HTTP GET request is received with that URL. I don't like having to scroll through a source file to discover such bindings and I actually prefer them to be defined at a separate place. In that sense, the Python 2 solution isn't good either and suffers from the same problem I described earlier: people try to be so concise that they loose sight of other goals.
- steveklabnik 17y agoThe Ruby code is not an annotation. It's very close to passing an anonymous function to a function. The definition of get is def get(path, opts={}, &block) See that &block? Here's the actual source of get: # Defining a `GET` handler also automatically defines # a `HEAD` handler. def get(path, opts={}, &block) conditions = @conditions.dup route('GET', path, opts, &block) @conditions = conditions route('HEAD', path, opts, &block) end Think of it as "I'm registering this block as a callback, to be called when this url is processed." I'm not sure how else you'd like to have a web DSL written; every web library I've used has worked this way.