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

···

--
Posted via http://www.ruby-forum.com/.

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 Mon, Feb 18, 2013 at 12:07 AM, Rob Marshall <lists@ruby-forum.com> wrote:

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

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

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/.

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.

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

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 Mon, Feb 18, 2013 at 12:07 AM, Rob Marshall <lists@ruby-forum.com> wrote:

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:

···

On 18 Feb 2013, at 08:06, Josh Cheek <josh.cheek@gmail.com> wrote:

On Mon, Feb 18, 2013 at 12:07 AM, Rob Marshall <lists@ruby-forum.com> wrote:

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

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).

Rob Marshall 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:

···

--
Posted via http://www.ruby-forum.com/\.

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 9:23 PM, tamouse mailing lists < tamouse.lists@gmail.com> wrote:

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 4:45 AM, Josh Cheek <josh.cheek@gmail.com> wrote:

On Mon, Feb 18, 2013 at 9:23 PM, tamouse mailing lists > <tamouse.lists@gmail.com> 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

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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

-Josh

···

On Tue, Feb 19, 2013 at 10:57 AM, Robert Klemme <shortcutter@googlemail.com>wrote:

On Tue, Feb 19, 2013 at 4:45 AM, Josh Cheek <josh.cheek@gmail.com> wrote:
> On Mon, Feb 18, 2013 at 9:23 PM, tamouse mailing lists > > <tamouse.lists@gmail.com> 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

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.

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 6:32 AM, Josh Cheek <josh.cheek@gmail.com> wrote:

On Tue, Feb 19, 2013 at 10:57 AM, Robert Klemme < > shortcutter@googlemail.com> wrote:

On Tue, Feb 19, 2013 at 4:45 AM, Josh Cheek <josh.cheek@gmail.com> wrote:
> On Mon, Feb 18, 2013 at 9:23 PM, tamouse mailing lists >> > <tamouse.lists@gmail.com> 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

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.

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

-Josh

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

···

On Wed, Feb 20, 2013 at 3:38 AM, Timothy Gregory <tigre7t@gmail.com> 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

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:

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On Thu, Feb 21, 2013 at 2:22 AM, Rob Marshall <lists@ruby-forum.com> wrote:

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:

--
Posted via http://www.ruby-forum.com/\.