*WHY* does this not work?

ok, so code:

str = 'foo'
=> "foo"
str.each_char do |c|
  c = 'x'
end
=> "foo"

WHY does str == 'foo' still?? i would expect it to be 'xxx'! this makes no
sense, and is *QUITE* annoying... i end up having to do things like this:

... i CAN'T do things like that for a string because it dsn't seem to do
that, but for an array i'd have to:

ary = ['f', 'o', 'o']
=> ["f", "o", "o"]
ary.each_index do |i|
  ary[i] = 'x'
end
=> ["x", "x", "x"]

GAH!!! least surprise?? least surprise my FOOT!!! even if there was a
*.each! method to do that i would be fine, *that* would be ok, none of this
'get the index and then do what you need to do and *THEN* set the stupid
block variable.... GRRRRRR!!!!

/vent
hex

···

--
my blog is cooler than yours: serialhex.github.com

The wise man said: "Never argue with an idiot. They bring you down to their
level and beat you with experience."

> Other than the fact Linux has a cool name, could someone explain why I
> should use Linux over BSD?

No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.

  -- Linus Torvalds' follow-up to a question about Linux

ok, so code:

str = 'foo'
=> "foo"
str.each_char do |c|
  c = 'x'
end
=> "foo"

WHY does str == 'foo' still??

Because each_char is not destructive to the original string's value. It
moves through the string as an array of characters and then passes each
one _by value_ to the block supplied. So while you might be able to
locally alter the value for that character, you don't have access to the
original string itself in the block.

i would expect it to be 'xxx'! this makes no
sense, and is *QUITE* annoying...

If you look at the source code for each_char you'll see that its return
value is the original string itself. Which is why you see "foo"
returned.

Sometimes it's your expectation that's wrong and not the library you're
using. :wink:

···

On Wed, Aug 10, 2011 at 03:52:59AM +0900, serialhex wrote:

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

ok, so code:

str = 'foo'
=> "foo"
str.each_char do |c|
c = 'x'
end
=> "foo"

WHY does str == 'foo' still?? i would expect it to be 'xxx'! this makes no
sense, and is *QUITE* annoying... i end up having to do things like this:

There are two reasons.
1) `c` is a variable. When you say `c = 'x'`, you are updating the object
that the variable c is pointing to, not invoking some sort of setter on the
string you are iterating over (which _is_ what you are doing in the array
example when you invoke the #= method).

2) Even if you were able to actually change the string, ie using `c.replace
'x'` rather than `c = x`, it wouldn't matter, because the char that `c` is
pointing to is a completely different string than `str`.

I don't know what you're trying to do, so I can't suggest a better solution,
but there is a way to do what you are asking using `String#gsub!`
str = "abc"
str.gsub!(/./) { |char| 'x' }
str # => "xxx"

... i CAN'T do things like that for a string because it dsn't seem to do
that, but for an array i'd have to:

ary = ['f', 'o', 'o']
=> ["f", "o", "o"]
ary.each_index do |i|
ary[i] = 'x'
end
=> ["x", "x", "x"]

GAH!!! least surprise?? least surprise my FOOT!!! even if there was a
*.each! method to do that i would be fine, *that* would be ok, none of this
'get the index and then do what you need to do and *THEN* set the stupid
block variable.... GRRRRRR!!!!

Try `Array#map!`

ary = ['f', 'o', 'o']
ary.map! { |char| 'x' }
ary # => ["x", "x", "x"]

···

On Tue, Aug 9, 2011 at 1:52 PM, serialhex <serialhex@gmail.com> wrote:

ok, so code:

str = 'foo'
=> "foo"
str.each_char do |c|
  c = 'x'
end
=> "foo"

Try this:

    str.gsub!(/\w/, 'x')

WHY does str == 'foo' still?? i would expect it to be 'xxx'!

The common way to handle things in Ruby is to *not* change the receiver
of a message. To do otherwise is surprising.

... i CAN'T do things like that for a string because it dsn't seem to do
that, but for an array i'd have to:

ary = ['f', 'o', 'o']
=> ["f", "o", "o"]
ary.each_index do |i|
  ary[i] = 'x'
end
=> ["x", "x", "x"]

. . . or use a map:

    ary.map! {|element| element.sub /\w/, 'x' }

GAH!!! least surprise?? least surprise my FOOT!!! even if there was a
*.each! method to do that i would be fine, *that* would be ok, none of this
'get the index and then do what you need to do and *THEN* set the stupid
block variable.... GRRRRRR!!!!

You're operating on c, not on str. It would be more surprising if when
operating on c it changed str, in my opinion.

The each method is an iterator -- not an editor. If you want to map an
operation onto an array, you should use the map method. If you want to
do substitutions on characters in a string, use a substitution method.
What could be less surprising than using the right tool for the job?

I think you're surprised because you expect one tool to do *everything*.
I would be pretty surprised if someone could make such a tool that wasn't
bad at everything it did.

···

On Wed, Aug 10, 2011 at 03:52:59AM +0900, serialhex wrote:

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

c represents a temporary variable with a copy of the char in it. This is always the case. Use the map and join methods if you want to construct a new string in that manner, and then set the variable pointing to the old string to the new string.

Blog: http://random8.zenunit.com/
Twitter: http://twitter.com/random8r
Learn: http://sensei.zenunit.com/
New video up now at http://sensei.zenunit.com/
real fastcgi rails deploy process! Check it out now!

···

On 10/08/2011, at 4:52 AM, serialhex <serialhex@gmail.com> wrote:

ok, so code:

str = 'foo'
=> "foo"
str.each_char do |c|
c = 'x'
end
=> "foo"

WHY does str == 'foo' still?? i would expect it to be 'xxx'! this makes no
sense, and is *QUITE* annoying... i end up having to do things like this:

... i CAN'T do things like that for a string because it dsn't seem to do
that, but for an array i'd have to:

ary = ['f', 'o', 'o']
=> ["f", "o", "o"]
ary.each_index do |i|
ary[i] = 'x'
end
=> ["x", "x", "x"]

GAH!!! least surprise?? least surprise my FOOT!!! even if there was a
*.each! method to do that i would be fine, *that* would be ok, none of this
'get the index and then do what you need to do and *THEN* set the stupid
block variable.... GRRRRRR!!!!

/vent
hex

--
my blog is cooler than yours: serialhex.github.com

The wise man said: "Never argue with an idiot. They bring you down to their
level and beat you with experience."

Other than the fact Linux has a cool name, could someone explain why I
should use Linux over BSD?

No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.

   -- Linus Torvalds' follow-up to a question about Linux

Whilst Ruby is probably a perfectly logical and self-consistent language
I personally think it has no right whatsoever to claim least surprise.

I've always said Matz finds Ruby unsurprising, but that's because he
wrote it.

···

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

> ok, so code:
>
> str = 'foo'
> => "foo"
> str.each_char do |c|
> c = 'x'
> end
> => "foo"
>
> WHY does str == 'foo' still??

Because each_char is not destructive to the original string's value. It
moves through the string as an array of characters and then passes each
one _by value_ to the block supplied. So while you might be able to
locally alter the value for that character, you don't have access to the
original string itself in the block.

so is there a way to do that? easily without jumping through hoops of
fire??

Sometimes it's your expectation that's wrong and not the library you're
using. :wink:

true, oh how annoyingly true... :stuck_out_tongue:
hex

···

On Tue, Aug 9, 2011 at 3:05 PM, Darryl L. Pierce <mcpierce@gmail.com> wrote:

On Wed, Aug 10, 2011 at 03:52:59AM +0900, serialhex wrote:

--
my blog is cooler than yours: serialhex.github.com

The wise man said: "Never argue with an idiot. They bring you down to their
level and beat you with experience."

> Other than the fact Linux has a cool name, could someone explain why I
> should use Linux over BSD?

No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.

  -- Linus Torvalds' follow-up to a question about Linux

From artima - The Philosophy of Ruby

Bill Venners: In an interview, you said "I designed Ruby to minimize my
surprise. I was very amazed when people around the world told me that Ruby
reduced their surprise and enhanced their joy of programming. Now I'm pretty
sure that programmer's minds are alike all over the world." Why the
principle of least surprise?

Yukihiro Matsumoto: Actually, I didn't make the claim that Ruby follows the
principle of least surprise. Someone felt the design of Ruby follows that
philosophy, so they started saying that. I didn't bring that up, actually.

I wanted to minimize my frustration during programming, so I want to
minimize my effort in programming. That was my primary goal in designing
Ruby. I want to have fun in programming myself. After releasing Ruby and
many people around the world got to know Ruby, they said they feel the way I
feel. They came up with the phrase the principle of least surprise. But
actually, it's often misunderstood.

Bill Venners: How is it misunderstood?

Yukihiro Matsumoto: Everyone has an individual background. Someone may come
from Python, someone else may come from Perl, and they may be surprised by
different aspects of the language. Then they come up to me and say, "I was
surprised by this feature of the language, so therefore Ruby violates the
principle of least surprise." Wait. Wait. The principle of least surprise is
not for you only. The principle of least surprise means principle of
least my surprise. And it means the principle of least surprise after you
learn Ruby very well. For example, I was a C++ programmer before I started
designing Ruby. I programmed in C++ exclusively for two or three years. And
after two years of C++ programming, it still surprised me.

···

On Wed, Aug 10, 2011 at 1:40 AM, Mike Stephens <rubfor@recitel.net> wrote:

Whilst Ruby is probably a perfectly logical and self-consistent language
I personally think it has no right whatsoever to claim least surprise.

I've always said Matz finds Ruby unsurprising, but that's because he
wrote it.

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

=> "xxx"

···

On Tue, Aug 9, 2011 at 9:11 PM, serialhex <serialhex@gmail.com> wrote:

so is there a way to do that? easily without jumping through hoops of
fire??

str.gsub(/./,"x") # :stuck_out_tongue:

--
Phillip Gawlowski

phgaw.posterous.com | twitter.com/phgaw | gplus.to/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
-- Leibniz

You want to iterate through a string and change individual characters?
Why not just do:

str = "farkle"
(0...str.size).each {|index| str[index] = 'x'}

···

On Wed, Aug 10, 2011 at 04:11:05AM +0900, serialhex wrote:

On Tue, Aug 9, 2011 at 3:05 PM, Darryl L. Pierce <mcpierce@gmail.com> wrote:

> On Wed, Aug 10, 2011 at 03:52:59AM +0900, serialhex wrote:
> > ok, so code:
> >
> > str = 'foo'
> > => "foo"
> > str.each_char do |c|
> > c = 'x'
> > end
> > => "foo"
> >
> > WHY does str == 'foo' still??
>
> Because each_char is not destructive to the original string's value. It
> moves through the string as an array of characters and then passes each
> one _by value_ to the block supplied. So while you might be able to
> locally alter the value for that character, you don't have access to the
> original string itself in the block.

so is there a way to do that? easily without jumping through hoops of
fire??

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

How I'd do it:
std.length.times { |i| str[i] = 'x' }

-Jonathan Nielsen

···

On Tue, Aug 9, 2011 at 1:11 PM, serialhex <serialhex@gmail.com> wrote:

so is there a way to do that? easily without jumping through hoops of
fire??

Morning,

···

On Tue, Aug 9, 2011 at 12:11 PM, serialhex <serialhex@gmail.com> wrote:

On Tue, Aug 9, 2011 at 3:05 PM, Darryl L. Pierce <mcpierce@gmail.com> > wrote:

so is there a way to do that? easily without jumping through hoops of
fire??

Maybe something like this would be of help

str.length.times do |i|
  str[i] = 'x'
end

John

The principle of least surprise means principle of least my surprise.

Very nicely put, Matz

···

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

ok, many responses, all very good and reasonable, but i guess my point is
kinda missed so i'll explain deeper...

here is an awesome kludge of a program i wrote last night:

yes it's ugly, and yes it's horrible, but it's not meant to be used for
anything more than what it was used for (which is quickly converting python
to ruby, and give kinda workable results most of the time, and since it's
simply single file programs that i was going to edit & fix later, i'm not
worried as to how ugly the translator is, or the translation, it just did
90% of my work for me)

look at the strip_python_loads method, that is the *best* way i can come up
with at the moment. yes i know there are better ways (to write this and the
entire program) but what are they? if i wanted to edit the contents of an
array while iterating through it how do it do it besides that? like i said,
a method such as each! which will allow you to modify the receiver would be
nice...
hex

p.s. oh, and if you want to fork & edit that gist to make it prettier & more
useful feel free to do so!

···

--
my blog is cooler than yours: serialhex.github.com

The wise man said: "Never argue with an idiot. They bring you down to their
level and beat you with experience."

> Other than the fact Linux has a cool name, could someone explain why I
> should use Linux over BSD?

No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.

  -- Linus Torvalds' follow-up to a question about Linux

Or use each_eith_index which is a bit nicer rather than constructing a range.

Blog: http://random8.zenunit.com/
Twitter: http://twitter.com/random8r
Learn: http://sensei.zenunit.com/
New video up now at http://sensei.zenunit.com/
real fastcgi rails deploy process! Check it out now!

···

On 10/08/2011, at 5:20 AM, "Darryl L. Pierce" <mcpierce@gmail.com> wrote:

On Wed, Aug 10, 2011 at 04:11:05AM +0900, serialhex wrote:

On Tue, Aug 9, 2011 at 3:05 PM, Darryl L. Pierce <mcpierce@gmail.com> wrote:

On Wed, Aug 10, 2011 at 03:52:59AM +0900, serialhex wrote:

ok, so code:

str = 'foo'
=> "foo"
str.each_char do |c|
c = 'x'
end
=> "foo"

WHY does str == 'foo' still??

Because each_char is not destructive to the original string's value. It
moves through the string as an array of characters and then passes each
one _by value_ to the block supplied. So while you might be able to
locally alter the value for that character, you don't have access to the
original string itself in the block.

so is there a way to do that? easily without jumping through hoops of
fire??

You want to iterate through a string and change individual characters?
Why not just do:

str = "farkle"
(0...str.size).each {|index| str[index] = 'x'}

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

As an alternative to this (although I'd just use #gsub!), if the character
doesn't change then you might as well do:

str.replace("x" * str.length)

To satisfy my curiosity, a crude benchmark:

$ cat str_replace_benchmark.rb
require "benchmark"
puts Benchmark.realtime { str = "hello, world!"; 10_000.times {
str.replace("x" * str.length) } }
puts Benchmark.realtime { str = "hello, world!"; 10_000.times {
str.gsub!(/./, "x") } }

$ ruby str_replace_benchmark.rb
0.007066011428833008
0.10264110565185547

···

On Tue, Aug 9, 2011 at 8:27 PM, John W Higgins <wishdev@gmail.com> wrote:

str.length.times do |i|
str[i] = 'x'
end

It has been pointed out several times that Array#map! does this.

In your case, though, it looks like you'd prefer Array#reject!

def strip_python_loads
  @file_lines.reject! { |line| line =~ /\s*from[ A-Za-z0-9\_.]*import\s*\w*/
}
end

···

On Tue, Aug 9, 2011 at 2:38 PM, serialhex <serialhex@gmail.com> wrote:

look at the strip_python_loads method, that is the *best* way i can come up
with at the moment. yes i know there are better ways (to write this and
the
entire program) but what are they? if i wanted to edit the contents of an
array while iterating through it how do it do it besides that? like i
said,
a method such as each! which will allow you to modify the receiver would be
nice...
hex

def strip_python_loads
      @file_lines.map! do |line|
        line = '' if line.match(/\s*from[ A-Za-z0-9\_.]*import\s*\w*/])
        line
      end
    end

Warning: I have not tested this code. I may have made a boneheaded
error. There may also be a better way to do this that would have
occurred to me if I was not multitasking.

···

On Wed, Aug 10, 2011 at 04:38:36AM +0900, serialhex wrote:

ok, many responses, all very good and reasonable, but i guess my point is
kinda missed so i'll explain deeper...

here is an awesome kludge of a program i wrote last night:
RTFKODE!!! · GitHub

yes it's ugly, and yes it's horrible, but it's not meant to be used for
anything more than what it was used for (which is quickly converting python
to ruby, and give kinda workable results most of the time, and since it's
simply single file programs that i was going to edit & fix later, i'm not
worried as to how ugly the translator is, or the translation, it just did
90% of my work for me)

look at the strip_python_loads method, that is the *best* way i can come up
with at the moment. yes i know there are better ways (to write this and the
entire program) but what are they? if i wanted to edit the contents of an
array while iterating through it how do it do it besides that? like i said,
a method such as each! which will allow you to modify the receiver would be
nice...

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

It depends on two things: whether you want to preserve the input lines or not.

First of all, I would do such stuff in a function that takes an argument. It keeps
you from being dependent on an instance variable. So I will use:

    def strip_python_loads(input)

This makes the code usable in more contexts.

Now, if you don't care about preserving line numbers, you can do the following:

    text = <<PYTHON
    from foo import bar

    batz
    PYTHON

    def strip_python_loads(input)
      input.reject { |line| line =~ /\s*from[ A-Za-z0-9\_.]*import\s*\w*/ }
      # or reject! if you want to destruct input
    end

    puts strip_python_loads(text.split("\n")).join("\n")

Preserving input can be done using #map:

    text = <<PYTHON
    from foo import bar

    batz
    PYTHON

    def strip_python_loads(input)
      input.map do |line|
        unless line =~ /\s*from[ A-Za-z0-9\_.]*import\s*\w*/
          line
        end
      end
      #same here, #map! works destructively
    end

    puts strip_python_loads(text.split("\n")).join("\n")
    # or even
    puts strip_python_loads(text.lines).join("\n")

Regards,
Florian

···

On Aug 9, 2011, at 9:38 PM, serialhex wrote:

ok, many responses, all very good and reasonable, but i guess my point is
kinda missed so i'll explain deeper...

here is an awesome kludge of a program i wrote last night:
RTFKODE!!! · GitHub

yes it's ugly, and yes it's horrible, but it's not meant to be used for
anything more than what it was used for (which is quickly converting python
to ruby, and give kinda workable results most of the time, and since it's
simply single file programs that i was going to edit & fix later, i'm not
worried as to how ugly the translator is, or the translation, it just did
90% of my work for me)

look at the strip_python_loads method, that is the *best* way i can come up
with at the moment. yes i know there are better ways (to write this and the
entire program) but what are they? if i wanted to edit the contents of an
array while iterating through it how do it do it besides that? like i said,
a method such as each! which will allow you to modify the receiver would be
nice...
hex

p.s. oh, and if you want to fork & edit that gist to make it prettier & more
useful feel free to do so!

--
my blog is cooler than yours: serialhex.github.com

The wise man said: "Never argue with an idiot. They bring you down to their
level and beat you with experience."

Other than the fact Linux has a cool name, could someone explain why I
should use Linux over BSD?

No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.

  -- Linus Torvalds' follow-up to a question about Linux

--
Florian Gilcher

smtp: flo@andersground.net
jabber: Skade@jabber.ccc.de
gpg: 533148E2

Editing the contents of an array while you're iterating it is generally considered bad programming practice... Because if you delete things, indexing becomes unpredictable. Using copies of arrays is usually a better practice generally.

Blog: http://random8.zenunit.com/
Twitter: http://twitter.com/random8r
Learn: http://sensei.zenunit.com/
New video up now at http://sensei.zenunit.com/
real fastcgi rails deploy process! Check it out now!

···

On 10/08/2011, at 5:38 AM, serialhex <serialhex@gmail.com> wrote:

ok, many responses, all very good and reasonable, but i guess my point is
kinda missed so i'll explain deeper...

here is an awesome kludge of a program i wrote last night:
RTFKODE!!! · GitHub

yes it's ugly, and yes it's horrible, but it's not meant to be used for
anything more than what it was used for (which is quickly converting python
to ruby, and give kinda workable results most of the time, and since it's
simply single file programs that i was going to edit & fix later, i'm not
worried as to how ugly the translator is, or the translation, it just did
90% of my work for me)

look at the strip_python_loads method, that is the *best* way i can come up
with at the moment. yes i know there are better ways (to write this and the
entire program) but what are they? if i wanted to edit the contents of an
array while iterating through it how do it do it besides that? like i said,
a method such as each! which will allow you to modify the receiver would be
nice...
hex

p.s. oh, and if you want to fork & edit that gist to make it prettier & more
useful feel free to do so!

--
my blog is cooler than yours: serialhex.github.com

The wise man said: "Never argue with an idiot. They bring you down to their
level and beat you with experience."

Other than the fact Linux has a cool name, could someone explain why I
should use Linux over BSD?

No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.

   -- Linus Torvalds' follow-up to a question about Linux