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:
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.
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.
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.
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!
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.
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).
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.
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'.)
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.
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.)
@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?
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.
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.
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.
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.
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?
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:
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.
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.
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
Question for students:
Jonathan reported that you like the screencasts. On what topics would you like additional screencasts?
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.
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.
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!
@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.
@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.
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.
@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).
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 `'
@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.
h = { "a" => 1 }
That works. So new comments will not have their straight quotes turned into curly.
Thanks!
When I paste Ruby code in here, all the indentation goes away. Is there a way to fix that?
@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 endThanks. Does that automatically indent my code? (If so, I want a tool like that to run locally on my Mac, too.)
@Ron Newman
You will have to indent the code yourself. The space bar is usually below the "B" key.
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'.)
@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
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.
@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
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
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
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.)
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'.
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)
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.
@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?
@Ken Busch
I don't know. I think the Kernel methods are something of a blemish on the language myself.
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.
@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.
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?
@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.
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?
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!
@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.
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?
@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
@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.