Adding camelize and underscore to String

Hi,

I know this is just a silly question, and that these methods are
available in Rails, but is this a viable way to add them to Ruby withOUT
Rails? e.g.:

class String
def camelize
self.split("").each {|s| s.capitalize! }.join("")
end
def camelize!
self.replace(self.split("
").each {|s| s.capitalize! }.join(""))
end
def underscore
self.scan(/[A-Z][a-z]/).join("_").downcase
end
def underscore!
self.replace(self.scan(/[A-Z][a-z]
/).join("_").downcase)
end
end

Thanks,

Rob

On Mon, Feb 18, 2013 at 12:07 AM, Rob M. [email protected]
wrote:

def camelize!

I’d probably implement them differently, but something like that should
get
you pretty far. If you wanted to go further, you could probably steal
some
implementation from Rails:

Or maybe just put ActiveSupport as a dependency, and require the
inflections (difficult to say, AS is an annoyingly big dependency).

-Josh

On 18 Feb 2013, at 08:06, Josh C. [email protected] wrote:

end

I’d probably implement them differently, but something like that should get you
pretty far. If you wanted to go further, you could probably steal some
implementation from Rails:
rails/activesupport/lib/active_support/inflector/methods.rb at b04c81d367323849a0019f6964639efaad0e9df0 · rails/rails · GitHub
Or maybe just put ActiveSupport as a dependency, and require the inflections
(difficult to say, AS is an annoyingly big dependency).

Nowadays it is less costly. By default the extensions are not loaded,
you need to cherry-pick them. Cherry-picking can happen at different
levels of granularity. This is explained at the top of the Active
Support core extensions guide:

Another couple questions, sorry…

In Python regular expressions have a “findall” which was added in
version 1.5.2 (i.e. it’s been around for quite some time, relatively
:-). Is the use of gsub in Ruby because scan is a recent addition to
String? Or is it just, for heavy use, too slow?

Also, is my use of self.replace() OK? I know that any methods with a ‘!’
are supposed to tell the user: Beware. But I wasn’t sure if modifying
self is a “normal” way to implement the ‘!’ methods.

Thanks,

Rob

Hi,

Thanks for the pointers to the ActiveSupport stuff. I’m new to Ruby so I
had to play with the code bit-by-bit to figure out what it was doing. At
this point I have to assume that using gsub is faster than the methods I
chose. And I realize that those methods are trying to cover a broader
set of cases than my code. I personally find them less “clear”, but I
assume they have merits and that they were chosen because of those
merits.

Thanks for the help,

Rob

Rob M. wrote in post #1097665:

Another couple questions, sorry…

In Python regular expressions have a “findall” which was added in
version 1.5.2 (i.e. it’s been around for quite some time, relatively
:-). Is the use of gsub in Ruby because scan is a recent addition to
String? Or is it just, for heavy use, too slow?

Scan is used to extract matches. The following:
.split("").each {|s| s.capitalize! }.join("")
.scan(/[A-Z][a-z]*/).join("
").downcase
…both construct a new array object containing a bunch of new string
objects, and iterate over the array, etc.

sub and gsub work directly on the original string without necessarily
constructing all those intermediate variables, instead using the
internal state of the regular expression engine. So in theory:

my_c_string.gsub(/([a-z])/) { $1.upcase }
my_j_string.gsub(/[A-Z]/) { "
#{$&.downcase}" }

or their more advanced cousins in ActiveSupport work faster and cleaner,
in a single fell swoop. I believe it’s a matter of taste as to which is
more readable, but personally I think the gsub versions get to the point
more readily.

Also, is my use of self.replace() OK? I know that any methods with a ‘!’
are supposed to tell the user: Beware. But I wasn’t sure if modifying
self is a “normal” way to implement the ‘!’ methods.

That’s how I always do it. If you’re wrong, we both are. :wink:

On Mon, Feb 18, 2013 at 9:23 PM, tamouse mailing lists <
[email protected]> wrote:

I do this a bit differently:

class String
def camelize
self = self.dup
self.camelize!
end

Should just be:
def camelize
dup.camelize!
end

module Camelizer

method defs as above

end

String.send(:include Camelizer)

Hmm. I assume what you meant to do was string.extend(Camelizer)
because
otherwise, what’s the point of pulling it out into its own module? Every
string gets it anyway b/c it’s included into the String class, and no
one
else can use it because it only makes sense on Strings.

On Mon, Feb 18, 2013 at 12:07 AM, Rob M. [email protected]
wrote:

I know this is just a silly question, and that these methods are
available in Rails, but is this a viable way to add them to Ruby withOUT
Rails? e.g.:

Not silly. Sometimes it is easier to reinvent the wheel, if the
wheel is easy to reinvent.

def underscore!
self.replace(self.scan(/[A-Z][a-z]*/).join(“_”).downcase)
end
end

I do this a bit differently:

class String
def camelize
self = self.dup
self.camelize!
end
def camelize!
self.replace… # as you have it
end
def underscore
self = self.dup
self.underscore!
end
def underscore!
self.replace… # as you have it
end
end

I’ve also seen it done instead of monkey patching, to insert a new
module into String:

module Camelizer

method defs as above

end

String.send(:include Camelizer)

On Tue, Feb 19, 2013 at 4:45 AM, Josh C. [email protected]
wrote:

Should just be:
def camelize
dup.camelize!
end

I’d do

def camelize
dup.tap {|s| s.camelize!}
end

or even

def camelize
dup.tap &:camelize!
end

Because usually #camelize! would return nil if the String was left
unchanged. In any case, this construct would make #camelize robust
against changes in #camelize!'s return value.

Cheers

robert

On Tue, Feb 19, 2013 at 10:57 AM, Robert K.
[email protected]wrote:

end
end

I guess I wouldn’t ever implement camelize! to return nil. I checked
ActiveSupport, and it is apparently not a method.

-Josh

hi
may i ask
is it the ruby method?
active_support
inflections
camelize
“allows you to specify acronyms in config/initializers/inflections.rb”
timo

On Wed, Feb 20, 2013 at 3:38 AM, Timothy G. [email protected]
wrote:

hi
may i ask
is it the ruby method?
active_support
inflections
camelize
“allows you to specify acronyms in config/initializers/inflections.rb”
timo

Right, ActiveSupport defines a camelize, but not a camelize!

Timothy G. wrote in post #1097937:

hi
may i ask
is it the ruby method?
active_support
inflections
camelize
“allows you to specify acronyms in config/initializers/inflections.rb”
timo

And, yes, inflections.rb allows you to specify acronyms. Although it
probably doesn’t care if it’s a real “acronym” or just something that
you want capitalized in a specific way. One example in the code is:
McDonald…a name, not an acronym. :slight_smile:

thanks Josh
active_support_inflections looks epic
like inbuilt attributes for ruby instance methods