[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

making a name like "Copy of...", "Copy 2 of..."

Max Williams

5/28/2009 11:32:00 AM

Here's a little ruby exercise - i'm a bit brain damaged today and can't
think of a nice way to do this.

I want a method where you pass a name as a string and it returns 'copy
of x' or 'copy 2 of x' eg

new_name("My Lesson")
=> "Copy of My Lesson"

new_name("Copy of My Lesson")
=> "Copy 2 of My Lesson"

new_name("Copy 10 of My Lesson")
=> "Copy 11 of My Lesson"

I can only come up with horrible looking solutions but i feel there's a
nice way to do it. Anyone?

cheers
max
--
Posted via http://www.ruby-....

5 Answers

Tim Hunter

5/28/2009 11:45:00 AM

0

Max Williams wrote:
> Here's a little ruby exercise - i'm a bit brain damaged today and can't
> think of a nice way to do this.
>
> I want a method where you pass a name as a string and it returns 'copy
> of x' or 'copy 2 of x' eg
>
> new_name("My Lesson")
> => "Copy of My Lesson"
>
> new_name("Copy of My Lesson")
> => "Copy 2 of My Lesson"
>
> new_name("Copy 10 of My Lesson")
> => "Copy 11 of My Lesson"
>
> I can only come up with horrible looking solutions but i feel there's a
> nice way to do it. Anyone?
>
> cheers
> max

Use a closure to keep track of how many copies you've made:

def copy(string)
x = 0
p = lambda do
x += 1
if x == 1
"Copy of #{string}"
else
"Copy #{x} of #{string}"
end
end
p
end

c = copy("My Lesson")

puts c.call
puts c.call
puts c.call


--
RMagick: http://rmagick.ruby...

Max Williams

5/28/2009 12:05:00 PM

0

Tim Hunter wrote:
> Max Williams wrote:
>> => "Copy 2 of My Lesson"
>>
>> new_name("Copy 10 of My Lesson")
>> => "Copy 11 of My Lesson"
>>
>> I can only come up with horrible looking solutions but i feel there's a
>> nice way to do it. Anyone?
>>
>> cheers
>> max
>
> Use a closure to keep track of how many copies you've made:
>
> def copy(string)
> x = 0
> p = lambda do
> x += 1
> if x == 1
> "Copy of #{string}"
> else
> "Copy #{x} of #{string}"
> end
> end
> p
> end
>
> c = copy("My Lesson")
>
> puts c.call
> puts c.call
> puts c.call

That method returns a proc though, rather than a string. Wouldn't that
mean that every time i want to call it i have to assign it to a variable
and then call that variable? Or am i being dumb? here's my
hacky-feeling solution:

def copied_name(source_name)
if source_name.match /^Copy of/i
new_name = source_name.gsub!(/^Copy of/i, "Copy 1 of")
elsif source_name.match /^Copy \d+ of/i
num = source_name.scan(/\d+/).first.to_i
new_name = source_name.gsub!(/^Copy #{num} of/i, "Copy #{num+1}
of")
else
new_name = "Copy of " + source_name
end
end

>> s = "My Lesson"
=> "My Lesson"
>> copied_name(_)
=> "Copy of My Lesson"
>> copied_name(_)
=> "Copy 1 of My Lesson"
>> copied_name(_)
=> "Copy 2 of My Lesson"


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

Rick DeNatale

5/28/2009 12:59:00 PM

0

On Thu, May 28, 2009 at 8:04 AM, Max Williams
<toastkid.williams@gmail.com> wrote:
>>> s = "My Lesson"
> => "My Lesson"
>>> copied_name(_)
> => "Copy of My Lesson"
>>> copied_name(_)
> => "Copy 1 of My Lesson"
>>> copied_name(_)
> => "Copy 2 of My Lesson"
>

Well, taking that approach how about:

def copied_name(source_name)
case source_name
when /^Copy of (.*)$/i
"Copy 1 of #{$1}"
when /^Copy (\d+) of (.*)$/i
num = $1.to_i
"Copy #{num+1} of #{$2}"
else
"Copy of #{source_name}"
end
end

s = "My Lesson" # => "My Lesson"
s = copied_name(s) # => "Copy of My Lesson"
s = copied_name(s) # => "Copy 1 of My Lesson"
s = copied_name(s) # => "Copy 2 of My Lesson"

However, since you used the i option on your regex maybe you wanted to
preserve the case of the "Copy of part" which this doesn't

s = "copy of My Lesson" # => "copy of My Lesson"
s = copied_name(s) # => "Copy 1 of My Lesson"
s = copied_name(s) # => "Copy 2 of My Lesson"
s = copied_name(s) # => "Copy 3 of My Lesson"

If so then this does:

def copied_name(source_name) # !> method redefined; discarding old copied_name
case source_name
when /^(Copy )(of .*)$/i
"#{$1}1 #{$2}"
when /^(Copy )(\d+)( of .*)$/i
num = $2.to_i
"#{$1}#{num+1}#{$3}"
else
"Copy of #{source_name}"
end
end

s = "My Lesson" # => "My Lesson"
s = copied_name(s) # => "Copy of My Lesson"
s = copied_name(s) # => "Copy 1 of My Lesson"
s = copied_name(s) # => "Copy 2 of My Lesson"

s = "copy of My Lesson" # => "copy of My Lesson"
s = copied_name(s) # => "copy 1 of My Lesson"
s = copied_name(s) # => "copy 2 of My Lesson"
s = copied_name(s) # => "copy 3 of My Lesson"



--
Rick DeNatale

Blog: http://talklikeaduck.denh...
Twitter: http://twitter.com/Ri...
WWR: http://www.workingwithrails.com/person/9021-ric...
LinkedIn: http://www.linkedin.com/in/ri...

Max Williams

5/28/2009 1:12:00 PM

0


> def copied_name(source_name)
> case source_name
> when /^Copy of (.*)$/i
> "Copy 1 of #{$1}"
> when /^Copy (\d+) of (.*)$/i
> num = $1.to_i
> "Copy #{num+1} of #{$2}"
> else
> "Copy of #{source_name}"
> end
> end
>

I'll go with this one, thanks Rick!

max
--
Posted via http://www.ruby-....

Brian Candler

5/28/2009 4:06:00 PM

0

A bit more compact:

def copied_name(source_name)
if source_name =~ /\ACopy (\d+ )?of (.*)\z/i
"Copy #{($1||1).to_i+1} of #{$2}"
else
"Copy of #{source_name}"
end
end

You can simplify ($1||1) to just $1, if you don't mind starting at Copy
1 of... instead of Copy 2 of...
--
Posted via http://www.ruby-....