Discussion: Q&A

September 13th, 2009 Leave a comment Go to comments

Q&A on Ruby/Rails topics.

  1. September 13th, 2009 at 19:20 | #1

    Question: What do the parts of the irb prompt mean?

    Here's an example:

    irb(main):001:0> 1 + 1
    => 2
    irb(main):002:0>

    The "001" is the statement number. If a statement isn't ocmplete in one line, the ":0" will go to ":1" - for example:

    irb(main):001:0> def foo
    irb(main):002:1>

    "def foo" starts a method definition - since it isn't complete, it indicates it with the "002."

    What's in parentheses -- here, "main" -- is the current value of "self." We haven't talked about self yet, but if, while in irb, you want to change self to another thing, you just say "irb thing" -- then any messages will go to thing unless otherwise specified:

    irb(main):001:0> thing = "foo"
    => "foo"
    irb(main):002:0> irb thing
    irb#1(foo):001:0> reverse
    => "oof"

    You can change the irb prompt: See the Pickaxe.

    A common problem with irb is when you type an unmatched token such as a quotation mark or a parenthesis or the start of a method, and you're not seeing any output. Typing a control c usually gets you out of the jam.

    John

  2. September 13th, 2009 at 19:20 | #2

    Question for students:

    Jonathan reported that you like the screencasts. On what topics would you like additional screencasts?

  3. September 13th, 2009 at 19:21 | #3

    Question for students:

    Jonathan said that students would like a "forum" for Q&A: More than this page? What I like about the simple blog comments is that it's very, very simple, and we spend our time discussing Ruby and Rails instead of worrying how the forum software works.

  4. Ron Newman
    September 13th, 2009 at 22:02 | #4

    At the 6:30 section, you mentioned several additional Ruby books (besides the required ones), but I didn't have a chance to take notes. Can you list them here? Thanks.

  5. September 15th, 2009 at 14:02 | #5

    john :
    Question for students:
    Jonathan reported that you like the screencasts. On what topics would you like additional screencasts?

    I would love to see a screencast on migration of a rails application through the environments (dev -> test -> prod) with granular examination of the different configurations. While I know that it is a bit early to ask this, it seems so intriguing to me, and it's all I could think of!

  6. Lateral Punk
    September 15th, 2009 at 14:36 | #6

    @Jeff Ancel
    I second Jeff's request. In addition, some explanation of how to get ruby & rails working on hosted servers like dreamhost or other ISP.

  7. September 15th, 2009 at 15:14 | #7

    @Jeff Ancel , @Lateral Punk

    Sure, no problem. Last year I did a few screencasts on deploying to slicehost.com; this year it will be Amazon's EC2.

  8. Ron Newman
    September 18th, 2009 at 23:08 | #8

    What configuration change do I need to make to irb so that I can reliably paste code into it?

    If i paste in the following line from http://e168f09.plugh.org/discussions/discussion-general/

    h = { “a” => 100, “b” => 200 }

    Here's what I get:

    irb(main):001:0> h = { ?a? => 100, ?b? => 200 }
    /Users/ronnewman/.ruby_versions/ruby-1.9.1-p243/lib/ruby/1.9.1/irb/ruby-lex.rb:347:in `block in lex_init': invalid byte sequence in UTF-8 (ArgumentError)
    from /Users/ronnewman/.ruby_versions/ruby-1.9.1-p243/lib/ruby/1.9.1/irb/slex.rb:236:in `call'
    from /Users/ronnewman/.ruby_versions/ruby-1.9.1-p243/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io'
    from /Users/ronnewman/.ruby_versions/ruby-1.9.1-p243/lib/ruby/1.9.1/irb/slex.rb:221:in `match_io'
    from /Users/ronnewman/.ruby_versions/ruby-1.9.1-p243/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
    (many more stack trace lines deleted here)

    So I guess I need to change irb's encoding to something other than UTF-8, but I have no idea how to do this.

  9. September 19th, 2009 at 08:01 | #9

    @Ron Newman

    I will see if I can have the quotes display as straight quotes. I don't think Ruby would interpret the curly quotes correctly even if IRB could take UTF-8 (which I've never figured out how to do myself -- you might remember that when I showed UTF-8 in lecture, I had to get the Japanese text from the keyboard: I couldn't paste it in).

  10. Ron Newman
    September 19th, 2009 at 08:40 | #10

    This seems to answer the issue with Japanese text:

    http://blogs.law.harvard.edu/hoanga/2009/09/08/getting-ruby-191p243-to-work-on-os-x-1058-with-japanese-input-support-on-irb/

    but even using irb --noreadline does not let me paste in the line

    h = { “a” => 100, “b” => 200 }

    Now I get:

    irb(main):003:0> h = { “a” => 100, “b” => 200 }

    SyntaxError: (irb):3: syntax error, unexpected $end, expecting '}'
    h = {
    ^
    from /Users/ronnewman/.ruby_versions/ruby-1.9.1-p243/bin/irb:12:in `'

  11. September 19th, 2009 at 10:00 | #11

    @Ron Newman

    The problem is the double-quotes. They're not straight quotes (as required in Ruby syntax). I will see if I can get WordPress to stop translating typed-in straight double-quotes into curly quotes.

    Meanwhile: Just type in the code, or manually edit curly double-quotes to straight double-quotes.

  12. September 19th, 2009 at 10:05 | #12

    h = { "a" => 1 }

    That works. So new comments will not have their straight quotes turned into curly.

  13. Ron Newman
    September 19th, 2009 at 10:18 | #13

    Thanks!

  14. Ron Newman
    September 21st, 2009 at 17:26 | #14

    When I paste Ruby code in here, all the indentation goes away. Is there a way to fix that?

  15. September 21st, 2009 at 19:45 | #15

    @Ron Newman

    Alright, I have just hacked the blog software. Do the following:

    If you have a snippet of Ruby code, do the following (except use SQUARE brackets instead of curly braces):

    {ruby}
    class Foo
    def Bar
    'bar'
    end
    end
    {/ruby}

    class Foo
      def Bar
        'bar'
      end
    end
    
  16. Ron Newman
    September 21st, 2009 at 19:46 | #16

    Thanks. Does that automatically indent my code? (If so, I want a tool like that to run locally on my Mac, too.)

  17. September 21st, 2009 at 19:55 | #17

    @Ron Newman

    You will have to indent the code yourself. The space bar is usually below the "B" key.

  18. Ron Newman
    September 23rd, 2009 at 08:49 | #18

    Is there a way to make the 'Search' box search the comments and not just the main text of posts here? (There's a lot more content here in comments than there is in 'main posts'.)

  19. September 23rd, 2009 at 09:51 | #19

    @Ron Newman

    I will fix that. For the short term, try typing this into Google:

    site:e168f09.plugh.org misread

    (to search for occurrences of the word "misread" at the site.)

    John

  20. Ron Newman
    September 23rd, 2009 at 10:55 | #20

    Scattered through the Pickaxe, I've seen a number of expressions like this one:

    Integer(x)

    where x is a string, and the expression's value is an integer. I don't understand what it means to use a class name this way, as if it were a method call. I would understand Integer.new(x), but that doesn't work.

  21. September 23rd, 2009 at 11:03 | #21

    @Ron Newman

    It's a method defined at the top-level: It just happens to start with a capital letter.

    It's probably something like:

    def Integer(x)
    x.to_i
    end

  22. Ron Newman
    September 23rd, 2009 at 11:32 | #22

    Thanks. Experimenting with irb, there seem to be a whole bunch of these strange methods:

    irb(main):002:0> Float("3.2")
    => 3.2
    irb(main):003:0> String([3,4,5])
    => "[3, 4, 5]"
    irb(main):004:0> Complex(44,99)
    => (44+99i)
    irb(main):011:0> Array(55) # why would anyone do this?
    => [55]

    but not this one:

    irb(main):014:0> Hash("area", 4)
    NoMethodError: undefined method `Hash' for main:Object

  23. September 23rd, 2009 at 11:38 | #23

    Array(something) is really useful!! If you do Array() on something that is already an Array, it isn't changed.

    Suppose you have a method that takes one parameter, but you want to allow someone to pass in a single item; but also handle arrays.

    def whatever(x)
    array_version = Array(x)
    # now deal with array_version
    end

  24. September 23rd, 2009 at 11:46 | #24

    A couple more things:

    To list these top-level methods:

    ri Kernel

    (you will see Array, Float, Integer, etc.)

    Then you can get the doc on each, e.g., ri Kernel#Array

    As for Hash: It probably isn't implemented because there's isn't an obvious way to "Hashify" an arbitrary object. It makes sense to convert an Array to Hash, but not really for a random object. (Whereas the behavior for Kernel#Array is plausible.)

  25. Ron Newman
    September 23rd, 2009 at 13:56 | #25

    OK, but I'm not sure what I get from Array(object) that I don't get from object.to_a , and the latter feels to me more 'Rubyish'.

  26. Ron Newman
    September 23rd, 2009 at 17:22 | #26

    This seems to answer some of my questions about Integer, Array, to_i, to_a, etc.:

    http://blog.grayproductions.net/articles/conversion_methods

    To my utter surprise, there is a Hash[] method (not a Hash() method)

  27. September 23rd, 2009 at 17:57 | #27

    Yes, I showed Hash[] in lecture, but need to say more about it.

    Note that while Array() is a Kernel method, [] is simply a class method on Hash.

  28. Ken Busch
    September 23rd, 2009 at 18:03 | #28

    @Ron Newman
    In C++, type coercion is sometimes expressed in this manner. (For example, Stroustrap seems to prefer int(x) over the more typically C-ish (int)x.) Possibly this is an imitation?

  29. September 23rd, 2009 at 18:53 | #29

    @Ken Busch

    I don't know. I think the Kernel methods are something of a blemish on the language myself.

  30. Ron Newman
    September 23rd, 2009 at 19:38 | #30

    I had thought that Capitalized names were reserved for constants (such as class and module names) and could not be used for anything else such as method names. Guess I was wrong.

  31. September 23rd, 2009 at 19:45 | #31

    @Ron Newman

    Thomas the method name "should start with a lowercase letter (or underscore) optionally followed by uppercase and lowercase letters, underscores, and digits" (PDF, 352).

    Or, as Flanagan/Matz says: "By convention, method names begin with a lowercase letter. (Method names can begin with a capital letter, but that makes them look like constants.)"

    Personally, I don't like it. The allowance of a method name to start with a capital letter seems to be exactly for have methods that are paired with classes to simulate constructors.

  32. Ken Busch
    September 23rd, 2009 at 21:08 | #32

    Are there good reasons to read Flanagan/Matz in addition to Thomas? How is the emphasis or exposition different? What kind of person might prefer it?

  33. September 23rd, 2009 at 21:29 | #33

    @Ken Busch

    I mentioned the book in my first lecture. It is very good for language concepts and code examples. The big problem with it as a starter book on Ruby is that there is no real tutorial. If you already know two or three languages, it's very good.

  34. Ron Newman
    September 23rd, 2009 at 22:13 | #34

    At your first section meeting, you recommended several other books, but I did not get a chance to take notes. Can you list them here?

  35. Scott Aldort
    September 23rd, 2009 at 22:49 | #35

    Is there a current downloadable version of the ruby ri docs for Windows users, in case I'm not connected to the internet? I looked on ruby-doc.org, but I could not find one that resembled what I see when I go to http://www.ruby-doc.org/core-1.9/index.html. Also, the downloads that are there seem somewhat behind in version.

    Thanks!

  36. September 23rd, 2009 at 23:16 | #36

    @Scott Aldort

    Scott, that's a good question -- I'll see what I can do. We should be able to provide you a zip of the rdoc.

  37. Peter Henstock
    September 28th, 2009 at 10:49 | #37

    I see a repeated theme in lectures that brevity is good. The first lecture advocated Ruby to reduce 10K java lines to 3K ruby lines. Furthermore, Assignment 1 is about one-liners. If coding was limited to typing speed or paper print-outs, this would make sense. However, most time is spent debugging so a shorter but even slightly less obvious code will usually cost more. Can you help provide insight into the philosophy that I'm obviously missing?

  38. September 28th, 2009 at 12:13 | #38

    @Peter Henstock

    I don't believe I have ever recommended writing "less obvious code" or using "dubious programming tricks" (see Paul Graham's essay below) as a practical matter. Let me know if I have. At least one of the one-liners does tend to result in code that is hard to understand, and you should use your own judgment to decide if the one-liner "rules" result in code that is problematic (hint: such problems might just be in the assignment to provide a learning experience about the disadvantages of writing one-liners in some cases).

    The pedagogical purpose of the one-liners assignment is to help you get "reading knowledge" of common Ruby idioms that experienced Rubyists use all the time. It is definitely a learning-by-doing exercise because your eyes would glaze over if I just handed out examples. Furthermore, every year we get answers to these problems that we've never even thought of, that are also better and clearer than our solutions. So it's a learning experience all around. It also helps you get a handle on unusual aspects of Ruby (compared to, say, C or Java), such as having a syntax for Hash literals, internal iterators, etc.

    The specific 10K v. 3K lines also resulted in a significant cost reduction for the company. The developers were very experienced, and much of the code was non-tricky and routine. So in their case, the reduction had less to do with "writing succinct code" and more to do with picking a language that is itself concise. They found the result to be far more maintainable, and, in the end, they probably saved themselves a lot of time and money, freeing them up to add lots of new features.

    I am also not really much of a zealot on this. If you write Java code that is 3 times as long as the equivalent Ruby code, that is spread across 3 times as many files, that requires you to use an IDE because the code is hard to traverse, then that's fine if it works for you.

    Having said that, the real distinction is between succinct code that is expressive and clear vs. bloated code that has elements that are distracting, given the scope of the project you're working on. One thing I do believe is that languages like Ruby and Python have been optimized for succinctness, whereas some other languages are designed to make the compiler easier to write/run and/or generate better object code.

    There are many eloquent defenses of succinct, expressive code. Here are a couple:

    http://www.paulgraham.com/power.html
    http://proquest.safaribooksonline.com.ezp-prod1.hul.harvard.edu/9780596510046/the_most_beautiful_code_i_never_wrote

  39. Brendan Shea
    October 4th, 2009 at 12:44 | #39

    john :
    Having said that, the real distinction is between succinct code that is expressive and clear vs. bloated code that has elements that are distracting, given the scope of the project you're working on. One thing I do believe is that languages like Ruby and Python have been optimized for succinctness, whereas some other languages are designed to make the compiler easier to write/run and/or generate better object code.

    @john

    For me, this hits the nail on the head. Having programmed in Java for 10+ years now, I can say a lot of the verbosity of Java has to do with distracting, repetitive elements. For instance, say I wanted a list of integer objects representing '1' and '2'. In Java, I'd have to do something like:

    List myList = new ArrayList();
    myList.add(Integer.valueOf(1));
    myList.add(Integer.valueOf(2));

    whereas the same code in Ruby would be

    a = [1, 2]

    Ruby is much more expressive and obvious in this case, and lets me eliminate redundant elements of the code (which turns out to be most of them!) To me this makes it easier to debug as well, since there are literally just less lines of code where a bug could be.

  1. No trackbacks yet.