
New Ruby 1.9 Features, Tips & Tricks - LiveTheDream
http://www.igvita.com/2011/02/03/new-ruby-19-features-tips-tricks/?utm_source=feedburner&utm_campaign=Feed%3A+igvita+%28igvita.com%29&utm_content=feed
======
JonnieCache
Also there are lots of other lovely methods on Array and Enumerable:

    
    
      * Array
        * new method:
          * Array#keep_if
          * Array#repeated_combination
          * Array#repeated_permutation
          * Array#rotate
          * Array#rotate!
          * Array#select!
          * Array#sort_by!
        * extended methods:
          * Array#{uniq,uniq!,product} can take a block.
    
      * Enumerable
        * New methods:
          * Enumerable#chunk
          * Enumerable#collect_concat
          * Enumerable#each_entry
          * Enumerable#flat_map
          * Enumerable#slice_before
    

[http://rbjl.net/27-new-array-and-enumerable-methods-in-
ruby-...](http://rbjl.net/27-new-array-and-enumerable-methods-in-
ruby-1-9-2-keep_if-chunk)

~~~
mapgrep
keep_if is like select! but slightly different; each_entry is like each but
slightly different; flat_map is like map but slightly different.

In no case are you saving more than a few keystrokes, yet any ruby coder who
works with other ruby coders now has more language "surface area" to learn in
order to read ruby.

This, guys, is how Perl became Perl. Oy.

keep_if is the truly maddening WTF eye-bleeding rage-inducing make-a-normally-
calm-rubyist-very-stabby one.

First off, it's a mutator but the name doesn't end in a bang. It should be
keep_if! but for some random reason isn't. Yet another example of how the
pleasant idea of using question marks for bool-returning methods
(file.exists?) and exclamations for mutators (file.delete!) is just that -- a
neat idea (very!) inconsistently applied and thus pointless. Ruby should use
method punctuations consistently or get rid of them, for heaven's sake.

keep_if is also egregious because it is the THIRD verb for doing basically the
same thing. We already had find_all and select (synonyms) and now select! and,
presumably, find_all!. So your workaday ruby coder gets to pick between
find_all, select and keep_if to pick items out of an array based on truthiness
of a callback. He gets to figure out which two are true synonymous and which
is a near-synonym , and then wonder/research why you would ever want to use
the near synonym.

Which brings us to the third reason keep_all is egregious, which is that
brings very, very little to the table. It is just like select! except it
always returns the object, whereas select! returns the object _except_ when no
changes are made, in which case it returns nil. In this regard select! behaves
like your other ruby mutators (string.sub! and string.gsub!, for example). Now
this behavior, which keep_if was invented to circumvent, can be annoying in a
very narrow range of circumstances, for example when you stick a mutator on a
var at the end of a method and take it for granted that it will always return
the thing it's mutating, as your return value, until one day your method is
randomly returning nil and you have to delete a _single character_ from your
method to fix this. But 99/100 times the whole reason you are using a mutator
is that you don't care about the return value just the side effect (the
mutation); if you cared about the rv you would just use the non mutator.

So keep_if is "fixing" a "problem" with an extremely minor scope and with an
extremely easy programmer fix.

Also, keep_if is a one off.

In other words:

If it's problematic that mutators in ruby return nil on non mutation, then the
Correct Solution, i.e. the non aneurism inducing one, is either to change how
ALL mutators work, say in 2.0, or to invent some kind of new standard
alternate syntax like say a double bang or something. Because there are a LOT
of mutators that work the way select! works.

The way NOT to fix this (supposed) mutator problem is to invent a one off
solution for one particular type of mutator, a solution that invents /a whole
different name/ for the method it is altering, thus setting the precedent of
sprawling the language. By the apparent reasoning behind keep_if we now need
something called like, oh I don't know, "rewrite_all" to similarly be like-
but-not-quite-like "gsub!". And "rewrite" to do same for "sub!", and so on and
so on for the other mutators until ruby is getting nearly as bloated and
unreadable as.... Perl. (Which I love and used to code in but, let's face it,
has some mmmmmhowdoyousay -- issues? -- with readability.)

So keep_if is a one-off inelegant language bloating solution to a non problem.
That's egregiousness three.

Egregiousness four is that keep_if was introduced _at the same time_ as the
thing it was invented to fix -- the (apparently sometimes) undesirable
behavior of select!. select! was introduced.... at the same time as keep_if.
Ugh. Facepalm.

So it's not like I'm going to stop using ruby or anything, and it's not like
anyone would care if I did, but I am going to have disagree with you a little
here about these new methods being "lovely," in the sense that methods that
will eventually send ruby spiralling into, at best, a /near brush/ with
morbid, Perl-esque language obesity are not "lovely" /in my humble opinion./

Anyway sorry for the rant! (And Ruby 1.9 does, in general, rock the Casba,
previous nothwithstanding.)

~~~
ollysb
Does feel a little like someone vandalised your car doesn't it. At this rate
someones going to be writing "ruby, the good bits".

------
masklinn
Most of it seems pretty nice (although I can hardly believe Ruby 1.8 does not
have named groups), but...

    
    
        tip "Ruby 1.9 supports 4 ways to call a proc!"
          f =->n {[:hello, n]}
          p f[:ruby] # => [:hello, :ruby]
          p f.call(:ruby) # => [:hello, :ruby]
          p f.(:ruby) # => [:hello, :ruby]
          p f === :ruby # => [:hello, :ruby]
    

wtf? Why are they writing that like it's a good thing?

~~~
philwelch
Ruby is a language that encourages developing internal DSL's for a lot of
problems. Having different syntaxes for the same thing gives you more
flexibility in defining DSL's. For instance, the "f[:ruby]" form lets you
define DSL's that intermix procs and hashes. The "f.(:ruby)" form is probably
the new standard shorthand, but the explicit "f.call(:ruby)" is clearly there
for backwards compatibility.

If you want a language where there's only one way to do it, I think there's a
language with that exact motto.

~~~
carbon8
_"If you want a language where there's only one way to do it, I think there's
a language with that exact motto."_

Be that as it may, in Ruby you should also follow conventions, write readable
code, use the most obvious choice when possible and avoid being unnecessarily
clever. Most of the core principles that Python promotes should also be heeded
when writing Ruby code. Ruby gives you the flexibility to choose different
options, but that doesn't mean that the flexibility should be abused.

~~~
oewolf
And it isn't abuse until it is used in a specific abusive way. Having the
options available to you isn't abusing it.

~~~
sigzero
Doesn't it "bloat" the language though?

~~~
oewolf
That is subjective. You can feel it is bloated, but I would call it handy and
expressive.

------
pyrhho
Conspicuously missing is the brilliant new Proc.curry method!

For those that don't know currying is a method that returns another Proc with
one fewer argument, so you can do: multiply = Proc.new { |x, y| x * y }
multiply_by_five = multiply.curry(5) multiply_by_five.call(3) # => 15

------
riffraff
Useful little thing: Object#tap. But Mostly, no mention of Fibers? :)

------
timmorgan
_"stabby proc"_

\-- sweet name for the new -> proc syntax.

~~~
briandoll
or perhaps better yet: "stabda"

------
loveatlonglast
Named captures in regular expressions looks really nice! I'm especially
excited to play with Oniguruma.

------
viggity
Named captures are a great way to document your regular expressions. Don't use
the "#" notation to comment on what the regex is doing, just name the group
instead!

.Net has had them for a long, long time and they are AWESOME!

It'd be cool to see Ruby get something like a MatchEvaluator, too

[http://msdn.microsoft.com/en-
us/library/system.text.regulare...](http://msdn.microsoft.com/en-
us/library/system.text.regularexpressions.matchevaluator.aspx)

A MatchEvaluator lets you much more complicated regex find replace. Currently,
find/replace only lets you re-order or remove groups or insert static text. A
MatchEvaluator lets you handle what to replace the match with code - meaning
you can call a webservice that will replace MM/DD/YY with the equivalent
Mayan/Persian/Lunar date.

~~~
rue
> _Currently, find/replace only lets you re-order or remove groups or insert
> static text._

I _must_ be misunderstanding you, but that's obviously incorrect.

    
    
        "foo 1 bar 2".gsub(/\d+/) {|m| m.to_i * 2 }
    

1.8 also. Does MatchEvaluator bring more to the table?

~~~
viggity
that looks exactly like a match evaluator, so it looks like ruby does have
that ability. Awesome.

