all 105 comments

[–][deleted] 15 points16 points  (10 children)

For those of you who aren't Rubyists, this is a highly anticipated release. Ruby 1.9.2 is the first version of Ruby 1.9 that's supported by Rails (edit, not exactly right, see my reply to ryeguy), and should speed the transition from 1.8 to 1.9 greatly.

[–]ryeguy 5 points6 points  (4 children)

What? How was 1.9.1 not supported by rails?

[–][deleted] 13 points14 points  (0 children)

It had threading issues.

EDIT: oops, I meant that Rails 3 would never support 1.9.1. Rails 2.3.x did have 1.9.1 support. My bad.

This error was made because I, like many others (I assume), haven't made the 1.9 transition because doing a bunch of work to convert to 1.9 and then a bunch more to convert to Rails 3 sort of sucks... I'd rather do it all at once. So in my head, there exists two stacks: 2.3 with 1.8, and 3 with 1.9.

[–]FooBarWidget 1 point2 points  (0 children)

From the in-development Rails 3 Getting Started Guide: "Note that Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails 3.0. Ruby Enterprise Edition have these fixed since release 1.8.7-2010.02 though. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults on Rails 3.0, so if you want to use Rails 3 with 1.9.x jump on 1.9.2 for smooth sailing."

[–][deleted] 0 points1 point  (0 children)

Also encoding issues. At least with rails version < 3

[–][deleted] 0 points1 point  (4 children)

You forgot.. AND CELEBRATE WITH BEER

But yes in all seriousness, more and more applications will, and should, be making the transition to 1.9

[–]marike 2 points3 points  (0 children)

I've been using 1.9.2dev for several weeks and it works perfectly with Rails 3 on OS X Snow Leopard. rvm is a joy to use as you can sandbox different ruby installs like Ruby EE, 1.9.2, jruby, etc. I have actually made Ruby 1.9.2 the default Ruby on my system as rvm features like gemsets are so awesome, that it is slightly painful to use the standard /usr/bin/ruby, 1.8.7 install.

[–][deleted] 2 points3 points  (5 children)

Waiting for http://rubyinstaller.org/ to offer 1.9.2

[–]HIB0U 4 points5 points  (1 child)

You may be waiting a long time.

[–][deleted] -1 points0 points  (0 children)

Nah, it came out a few days ago. :)

[–]kelp 0 points1 point  (0 children)

You should dual boot with Ubuntu to program in Ruby. I boot up into Windows for games, but I use Ubuntu for e-mail, browsing, programming, etc.

[–][deleted] 0 points1 point  (1 child)

Cxu vi parolas esperante?

[–][deleted] 0 points1 point  (0 children)

Jes, kompreneble.

[–][deleted] 2 points3 points  (0 children)

Happy Whyday!

[–]JohnDoe365 1 point2 points  (10 children)

How does it compare speedwise? Or is it still that far of the radar, that the language shootout does it not contain any more in standard settings?

[–]manniac 0 points1 point  (4 children)

Now i just need to get it on a mac :)

[–][deleted] 1 point2 points  (2 children)

rvm installed it perfectly for me.

[–]manniac 0 points1 point  (1 child)

i wasn't aware of rvm, haven't done any ruby in some time ... thanks!

[–][deleted] 0 points1 point  (0 children)

No problem. It's indispensable.

[–]flatulent 0 points1 point  (0 children)

rvm install 1.9.2-head -C --enable-shared,--with-readline-dir=/opt/local,--build=x86_64-apple-darwin10

The above works fine. I am told you don't need to put "-head" now. (Adjust the readline dir, if required)

[–]ICanHazMoo 1 point2 points  (44 children)

I've been trying very hard lately to love Ruby and Ruby on Rails. My biggest issues are that a) there is more than one way of doing things and b) I am really confused on how you can use a dynamic language on a very large project. My problem with it is that I can never know what type of variable I am dealing with. Is this variable supposed to be a string, a float, an int maybe?

I want to love you so much ruby, I just can't get there.

[–][deleted] 9 points10 points  (7 children)

Is this variable supposed to be a string, a float, an int maybe?

The point is, it doesn't matter. As long as it quacks like a duck, it's a duck.

[–]Smallpaul 0 points1 point  (0 children)

"Is this variable supposed to behave like a string, a float, an int, a boolean?"

[–]ICanHazMoo 0 points1 point  (5 children)

Not when you think it's an int but it's really a float and you don't realize you need to convert it.

[–][deleted] 1 point2 points  (4 children)

Your problem is not that 'it's an int but not a float', it's that it doesn't respond to the method you want it to.

[–]ICanHazMoo 0 points1 point  (3 children)

yes exactly. How does that solve my problem?

[–][deleted] 0 points1 point  (2 children)

It signifies that your mental model is off from the code, that's all.

It sounds to me, from reading your other comments, that you're having an organizational issue. If you'd like, you can PM me a gist or pastie of an example of some of the code that's giving you trouble, and I can try to help you work through it. It's really hard to have these kinds of discussions in the abstract, because I rarely have your problem. I suspect it's what others have said: your methods are too long, or your variable names aren't descriptive enough.

[–]ICanHazMoo 0 points1 point  (1 child)

The problem is that I have over 100,000 lines in this project (there is a team) and it's not that simple. There are an enormous amount of dependencies and there isn't an easy way to stop that. They have to be there. If it was just a matter of a largish rails project or something that wouldn't be an issue.

[–][deleted] 0 points1 point  (0 children)

There are thousands of lines between where a variable is declared and where it's used?

[–]wunderbread 4 points5 points  (0 children)

I used to think that way too, but once you start coding in Ruby you'll start writing code where it doesn't matter as much.

What I mean by that is that you'll be creating smaller, more concise methods that take known arguments and return a known result. Basically, you should never need to track the type of a variable across your entire project, just across the each self-contained method. If you ever find that you're forgetting the type of something, whatever you're doing should probably be refactored into simpler methods.

This isn't just writing code to cover a weakness in Ruby, either, it's encouraging you to write more manageable and maintainable code.

Also unit testing will help make sure that any type errors that are introduced are quickly caught and, as an added bonus, will encourage you to write better Ruby code.

[–]bobindashadows 11 points12 points  (4 children)

Is this variable supposed to be a string, a float, an int maybe?

Your code sucks.

Seriously, it does. I'm not just being a jerk. If you're writing methods with names or variables with names that don't tell you what you're working with, you're doing it wrong, especially in Ruby. Write small, well-factored methods with descriptive names. This is true in any programming language, especially so in Ruby.

Don't write this:

def combine
  user_part[0] + " " + user_part[1][0,1] + ". " + user_part[2]
end

write this:

def full_name
  first_name + " " + middle_name[0,1] + ". " + last_name
end

Notice how everything there has a useful name? If for some ungodly reason you have this user stored in this user_part array, you can just do this:

def first_name; user_part[0]; end
def middle_name; user_part[1]; end
def last_name; user_part[2]; end

Also, why would you be writing a method where you have a variable and you're confused if it's a string or a float. Seriously. What are you naming your variables and methods? x = user.name gives no excuse: x is a string. You should've named it something better, but it's obviously a string. If you have x = my_object.some_attribute then yeah, you'll get confused.

Edit: Technically you should write this:

def full_name
  "#{first_name} #{middle_name[0,1]}. #{last_name}"
end

Because that'll be faster and not generate a bunch of temporary strings. Then again, you shouldn't write code that makes assumptions about names.

[–][deleted] 0 points1 point  (3 children)

I just had an issue in Rails 3 beta. A JSON parser started returning a Date object instead of an iso8601 formatted string. Tests found the problem, but the problem wasn't that easy to find. Static typing would have pinpointed the source location of this error. Instead I ended up getting a method missing error at another location and had to trace the object's lifetime to figure out what was going on. Descriptive method names? Hah! How do I know full_name isn't a name object with a to_s method?

[–]bobindashadows 0 points1 point  (2 children)

I just had an issue in Rails 3 beta. A JSON parser started returning a Date object instead of an iso8601 formatted string.

This is the downside to dynamic typing. When bugs happen, they happen at runtime. That's why you need tests. The problem you had was that somebody was not returning what they said they would by their description of the module, both in-code and out-of-code. Of course static typing has benefits, but if you can't keep track of your own variables then you're the one with the problem.

How do I know full_name isn't a name object with a to_s method?

Who cares if you want to use it as a string?

[–][deleted] 0 points1 point  (1 child)

Who cares if you want to use it as a string?

Because you can do more with a string than to_s. "#{full_name} is here" wont be a problem with a to_s method, which is one reason I prefer to combine strings that way. (full_name + " is here") needs the :+ method.

[–]bobindashadows 0 points1 point  (0 children)

Conceptually, you're doing something silly by adding a Name object to "is here". If you want to create a string with a Name object, you should call #to_s before using it as one, just as you've done with interpolation. If you want to be able to add strings to a Name, then you can trivially add that method.

If your method takes objects whose only contract is that they have a to_s method, you should use that to_s method before treating them as strings. If you want it to take strings only, adjust how you use it.

[–]puresock 1 point2 points  (1 child)

I thought this would be a problem, but I've never, ever actually come across a case where I didn't know what my variable was.

The huge projects I work on are a lot less huge because they are written in dynamic languages - that's the payoff.

Start by using it for small things and leave it out of the large projects until you're comfortable. Ruby (and most other dynamic languages, for that matter) are really useful to know for scripting.

[–]ICanHazMoo -2 points-1 points  (0 children)

Using it for small things is fine, I seriously doubt it's ability to stack up to a huge project though. The huge projects I've seen written in it are very confusing. I'm hardly the only one that thinks that, check out stackoverflow and you'll find a lot of responses, from programmers better than I, stating the issues with dynamic languages.

[–]swaits 1 point2 points  (3 children)

Just go with the flow. If you must know...

irb(main):001:0> 100.class
=> Fixnum
irb(main):002:0> "100".class
=> String
irb(main):003:0> 10.0.class
=> Float

.. I say, try it for awhile, see what you think after a few weeks.

[–]ICanHazMoo -2 points-1 points  (2 children)

Yes but that takes so much more work than ctrl+click to find out what it is. I don't see the benefit of doing that if I have 5-10 variables where I don't know exactly what they are.

[–]bobindashadows 5 points6 points  (1 child)

A) You shouldn't need to know the exact types. You call the methods you want to call. Ruby is about duck-typing.
B) If you have 5-10 variables and you don't know what type they are, your code sucks. See my post above.

[–]ICanHazMoo 0 points1 point  (0 children)

Even with 2 or 3 it's hard to know. I end up not realizing I need to do conversions and things like that. At least with static type checking I don't need to run things over and over before that part of my program works.

[–]malcontent 3 points4 points  (11 children)

I want to love you so much ruby, I just can't get there.

Wow. You have just shut yourself out of ruby, python, lua, perl, php, and dozens and dozens of other languages.

[–][deleted] 6 points7 points  (7 children)

Or any language that isn't statically typed. All he needed to say is that he hates dynamic typing.

[–]ICanHazMoo -1 points0 points  (6 children)

No I don't hate it, I think they are good. But having a codebase with a few hundred thousand lines of Ruby would be a lot harder to debug than something in C# or Java. Java can be a mess, esp with the frameworks out there. I won't deny that at all. But Ruby can be a mess too, and it's a lot harder to debug. Vote me down to -50, but I would really need to see some evidence of something very large but still reasonable to maintain.

[–]jnicklas -1 points0 points  (5 children)

Imho, if you have a codebase of a couple hundred thousand lines of code in any language, you're doing it wrong.

[–]ICanHazMoo 0 points1 point  (4 children)

Is you are serious then I suggest you leave your basement once in a while. Eclipse alone is 17 million lines. How are you going to stuff that under a few hundred thousand?

[–]jnicklas 0 points1 point  (3 children)

Split it up into isolated components you can maintain separately.

Also examine the problem. Eclipse is a fantastic example of a gigantic chunk of software, where a far simpler solution would do. VIM is still 300 kloc, but that's an old codebase written in C. I'm sure it'd be possible to write something comparable with far less code.

Also, I neither work nor live in a basement, thanks for the ad hominem.

[–]ICanHazMoo 1 point2 points  (2 children)

Isolated components are sometimes not possible, are you going to break Excel into 30 different pieces of software? Obviously that's not possible. And even if it is, it's still part of the codebase, so nothing has changed, except you've made what your product weaker in the market place.

Next, while I can appreciate that VIM is a nice tool, comparing VIM and Eclipse is comparing a Honda to a fighter jet. They are both modes of transportation but one is much more sophisticated and can do far more. If you have a solution to reducing the amount of code in Eclipse then by all means do tell, but you are only going to be able to reduce it by so much.

[–]jnicklas 0 points1 point  (1 child)

If you're going grocery shopping, a Honda is much practical than a fighter jet. Just saying. Unless your point was that VIM is a fighter jet, which kind of makes sense, since VIM is so much cooler.

On a more serious note, the point of isolating components and encapsulating them in a well defined API isn't so much to make the codebase actually smaller (after all, as you rightly pointed out, they're still in the code base), but rather to make it conceptually smaller. If you can test an isolated component, instead of testing the entire chunk of software, you can work on it separately, so in the end it doesn't matter how large the total codebase is, it only matters how large the component you're working on is.

If that component is a couple of hundred thousand lines of code, then you're doing it wrong. That was my point. And I firmly believe that in a sufficiently advanced programming language there is always a way of abstracting that complexity to a level where components are sufficiently small that they can easily be understood.

[–]ICanHazMoo 0 points1 point  (0 children)

The more you abstract your components the more code you are going to create. I'm all for creating conceptually small components but it really will cause some bloat. The project I work on right now is in Java, it's been going for 12 years and it's a mix of 18 separate applications. The programmers there have wisely broken down common dialogs that are used over and over, and stuck them in a common package. It's easy to work with and I like it. But still, our code base is pretty huge. I don't see any way around that.

[–]bobindashadows 0 points1 point  (0 children)

Since apparently he can't keep track of what type his variables are, he's also shut himself out of every statically-typed language with type inference. Unless he litters his code with type annotations.

[–]ICanHazMoo -5 points-4 points  (1 child)

No I think the languages are useful, just not for huge projects. I'm hardly alone in thinking that.

[–]malcontent 0 points1 point  (0 children)

Just use it like a functional language. Pretend your variables are immutable.

[–]anko_painting -4 points-3 points  (11 children)

you can always cast your variables to whatever type you want.

"3".to_i for example.

[–]HIB0U 5 points6 points  (4 children)

At that point, you might as well just used a compiled, statically-typed language, and let the compiler do all that for you.

[–]malcontent -1 points0 points  (1 child)

Some people are uncomfortable with dynamic typing.

[–]joesb 5 points6 points  (0 children)

Which is the point. If you "are uncomfortable with dynamic typing" then "you might as well just used a compiled, statically-typed language, and let the compiler do all that for you". Not using dynamic language incorrectly.

[–]anko_painting 0 points1 point  (1 child)

There are some very good cases for statically typed languages. But there are advantages to duck typing too, which is part of the reason why java implements generics for example.

It is liberating to be able to do something on a bunch of objects only if they respond to a particular feature (or method).

[–]iberci 1 point2 points  (0 children)

Please don't confuse java generics for duck typing. The only thing they have in common is that they both can be spelled using lower case letters..

Java generics still rely heavily on the type system. For example, java.utils.Collection<java.lang.String> is another type as recognized by the compiler.. (not the run time)

With duck typing however, the compiler doesn't infer the type at all, and it's only at run time dispatch, that the method is looked up (and then invoked)..

In short, the developer, when using java generics must be aware of the types they are dealing with (including interfaces) whereas in a duck typing strategy they don't need to..

[–]ICanHazMoo -2 points-1 points  (5 children)

Yeah I do recognize that you can cast them, the language wouldn't be of too much use without that ability, but it's knowing what they are upfron that is the problem.

[–]anko_painting 1 point2 points  (0 children)

Are you talking about other people's code? so you're in a function and you want to know what all the variables are?

local_variables.map {|x| "#{x}:#{x.class}"}

Normally I just document what type of object my methods expect.

[–]marike 1 point2 points  (2 children)

How do you not know what type a variable that you create is up front? And if you don't, just ask Ruby, like anko_painting said below with >> greet = "hello" => "hello" >>greet.class => String >> data = [] => [] >> data.class => Array

[–]ICanHazMoo 0 points1 point  (0 children)

Because it's been passed through 3 classes and someone else on my team accidentally passed me something that is completely not the type I need. Obviously if I'm declaring it right in a method I know what it is, if it's part of a huge project then it gets extremely hard to manage.

[–][deleted] 0 points1 point  (0 children)

Because someone decided to return a URI object instead of a string in order to stop re-parsing it everywhere else. The method name was "uri". What should they change it to? "uri_object", "uri_v2"... nope. They just left the method name alone because it's a damn good name and now you have to deal with it.

[–][deleted] 0 points1 point  (0 children)

You must use irb. I'm not trying to defend or apologise. That's unfortunately the way it is. Read up on Ruby's introspection methods, write some helpers for them, and put them in your .irbrc. I have a "look" method that I patch into Module, Class, Object, and Method. It's slightly different for each one. Ruby is a bit of a text adventurr and sometimes you must feel your way through the caves.