(newbie) I can’t for my life figure out how to create bang methods. Please
help.
~Jon Hurst
class Foo
def bang_method!
# probably something that modifies a Foo in place
end
end
-a
···
On Tue, 20 Apr 2004, Jon Hurst wrote:
(newbie) I can’t for my life figure out how to create bang methods. Please
help.
~Jon Hurst
–
EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================
On reflection, perhaps I have not been clear enough. I would like to create
bang methods of some math functions (mostly abs), but I don’t know how to
modify the reciever in place because the value of self cannot be changed.
It’s not really important that I be able to write these bang methods, but I
would very much like to understand how one would do it.
Class Numeric
def abs!
??
end
end
~Jon Hurst
“Jon Hurst” jon@jonathan.hurst.name wrote in message
news:EbWci6$T5+30@cc.usu.edu…
···
(newbie) I can’t for my life figure out how to create bang methods. Please
help.
~Jon Hurst
This problem bit me repeatedly. It’s sort of a design feature, not a
flaw, as I understand it.
Certain base classes are not meant to be mutable, per the design of the
language. The ‘best’ way to do this, I’ve been told, is what I did for
my MutableTime class, to wit:
a) Create a new class (that doesn’t inherit from the other)
b) Keep your own instance variable that is the base class
c) When you need to modify the instance, swap out your instance,
otherwise
d) Pass method calls on to the instance.
For example, something like
class MyNumber
def initialize( initialValue=nil )
@n = initialValue || 0
end
def abs!
@n = @n.abs
end
def method_missing(meth, *args, &block) # :nodoc:
@n.send(meth, *args, &block)
end
end
There are various drawbacks to this, but…there you go. There’s an
answer, anyhow.
···
On Apr 21, 2004, at 11:34 AM, Jon Hurst wrote:
[…] I would like to create bang methods of some math functions
(mostly abs), but I don’t know how to modify the reciever in place
because the value of self cannot be changed.
–
(-, /\ / / //
Some objects provide a .replace(): strings, hashes…
I don’t know about numerics but they look like immutable to me,
so you may need a Facade delegating most of the work to the
immutable object. I think there is a delegator.rb that may help,
if delegate can be changed on the fly (I haven’t checked)
Jean-Hugues
···
At 02:34 22/04/2004 +0900, you wrote:
On reflection, perhaps I have not been clear enough. I would like to create
bang methods of some math functions (mostly abs), but I don’t know how to
modify the reciever in place because the value of self cannot be changed.
It’s not really important that I be able to write these bang methods, but I
would very much like to understand how one would do it.Class Numeric
def abs!
??
end
end~Jon Hurst
Jon Hurst wrote:
On reflection, perhaps I have not been clear enough. I would like to create
bang methods of some math functions (mostly abs), but I don’t know how to
modify the reciever in place because the value of self cannot be changed.
It’s not really important that I be able to write these bang methods, but I
would very much like to understand how one would do it.Class Numeric
def abs!
??
end
end
Even if you had a way to implement some bang-abs, what would you expect
-4.abs! to be?
Happy rubying
Stephan
Hi –
“Jon Hurst” jon@jonathan.hurst.name writes:
On reflection, perhaps I have not been clear enough. I would like to create
bang methods of some math functions (mostly abs), but I don’t know how to
modify the reciever in place because the value of self cannot be changed.
It’s not really important that I be able to write these bang methods, but I
would very much like to understand how one would do it.Class Numeric
def abs!
??
end
end
Not being able to assign to self actually isn’t the issue (no method
can do that). I think you want this:
x = -1
x.abs!
to result in x == 1, but that isn’t how bang methods work; i.e., they
don’t assign a new object to a variable, but rather they change an
object in place (and, if there are one or more variables referencing
that object, those variables don’t “know” that this has happened).
irb(main):002:0> x = [1,2]
=> [1, 2]
irb(main):003:0> x.id
=> 537881530
irb(main):004:0> x.reverse!
=> [2, 1]
irb(main):005:0> x.id
=> 537881530
Nothing has happened to x in this example (no reassignment) but the
underlying array has been modified.
The problem with abs! is that you can’t modify a number in place,
because numbers are immediate values (even when referenced by
variables), and there’s only one copy of each in existence. So if you
did this:
-1.abs!
then henceforth 1 + -1 would be 2, because you would have changed -1
itself to 1 (not just assigned 1 to a variable that previously
referenced -1). The same would be true of this:
x = -1
x.abs! # x is the immediate value -1
This is also why there are no ++ and – operators in Ruby. 1++ would
mean that the actual number 1 would henceforth mean 2.
David
···
–
David A. Black
dblack@wobblini.net
I would assume he would expect:
x = -4
x.abs!
p x => 4
···
On Apr 21, 2004, at 3:59 PM, Stephan Kämper wrote:
Even if you had a way to implement some bang-abs, what would you
expect -4.abs! to be?
–
(-, /\ / / //
i think we should try to talk matz into this for a minor release. maybe the
release slated for 2005-04-01?
-a
···
On 21 Apr 2004, David Alan Black wrote:
This is also why there are no ++ and – operators in Ruby. 1++ would mean
that the actual number 1 would henceforth mean 2.
–
EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================
“Gavin Kistner” gavin@refinery.com schrieb im Newsbeitrag
news:245541A6-93BD-11D8-A280-000A959CF5AC@refinery.com…
[…] I would like to create bang methods of some math functions
(mostly abs), but I don’t know how to modify the reciever in place
because the value of self cannot be changed.This problem bit me repeatedly. It’s sort of a design feature, not a
flaw, as I understand it.Certain base classes are not meant to be mutable, per the design of the
language. The ‘best’ way to do this, I’ve been told, is what I did for
my MutableTime class, to wit:
a) Create a new class (that doesn’t inherit from the other)
b) Keep your own instance variable that is the base class
c) When you need to modify the instance, swap out your instance,
otherwise
d) Pass method calls on to the instance.For example, something like
class MyNumber
def initialize( initialValue=nil )
@n = initialValue || 0
end
One check too much.
def abs!
@n = @n.abs
enddef method_missing(meth, *args, &block) # :nodoc:
@n.send(meth, *args, &block)
end
Those two can be combined.
end
How about:
class MyNumber
def initialize( initialValue = 0 )
@n = initialValue
end
def method_missing(meth, *args, &block)
if /!$/ =~ meth.to_s
@n = @n.send(meth.to_s[0…-1], *args, &block)
else
self.class.new @n.send(meth, *args, &block)
end
end
eql, == etc still missing here
end
x = MyNumber.new -10
p x
x.abs!
p x
Regards
robert
···
On Apr 21, 2004, at 11:34 AM, Jon Hurst wrote:
Well… something++ could get expanded into (something = something.++()) ?
And ++something get expanded into (tmp = something, something =
something.++(), tmp)
Pure syntax sugar.
Then you can:
def ++()
self + 1
end
I think += does that already, doesn’t it ?
There are other reasons why there is no ++ in Ruby.
Jean-Hugues
···
At 08:19 22/04/2004 +0900, you wrote:
Hi –
“Jon Hurst” jon@jonathan.hurst.name writes:
On reflection, perhaps I have not been clear enough. I would like to create
bang methods of some math functions (mostly abs), but I don’t know how to
modify the reciever in place because the value of self cannot be changed.
It’s not really important that I be able to write these bang methods, but I
would very much like to understand how one would do it.Class Numeric
def abs!
??
end
endNot being able to assign to self actually isn’t the issue (no method
can do that). I think you want this:x = -1
x.abs!to result in x == 1, but that isn’t how bang methods work; i.e., they
don’t assign a new object to a variable, but rather they change an
object in place (and, if there are one or more variables referencing
that object, those variables don’t “know” that this has happened).irb(main):002:0> x = [1,2]
=> [1, 2]
irb(main):003:0> x.id
=> 537881530
irb(main):004:0> x.reverse!
=> [2, 1]
irb(main):005:0> x.id
=> 537881530Nothing has happened to x in this example (no reassignment) but the
underlying array has been modified.The problem with abs! is that you can’t modify a number in place,
because numbers are immediate values (even when referenced by
variables), and there’s only one copy of each in existence. So if you
did this:-1.abs!
then henceforth 1 + -1 would be 2, because you would have changed -1
itself to 1 (not just assigned 1 to a variable that previously
referenced -1). The same would be true of this:x = -1
x.abs! # x is the immediate value -1This is also why there are no ++ and – operators in Ruby. 1++ would
mean that the actual number 1 would henceforth mean 2.
David
Hi –
“Ara.T.Howard” ahoward@fattire.ngdc.noaa.gov writes:
···
On 21 Apr 2004, David Alan Black wrote:
This is also why there are no ++ and – operators in Ruby. 1++ would mean
that the actual number 1 would henceforth mean 2.i think we should try to talk matz into this for a minor release. maybe the
release slated for 2005-04-01?
And we could speed it up:
2005–
22.times { 1++ }
Hmmm… I see the makings of a Hollywood sci-fi blockbuster…
David
–
David A. Black
dblack@wobblini.net
Hi –
Jean-Hugues ROBERT jean_hugues_robert@yahoo.com writes:
The problem with abs! is that you can’t modify a number in place,
because numbers are immediate values (even when referenced by
variables), and there’s only one copy of each in existence. So if you
did this:-1.abs!
then henceforth 1 + -1 would be 2, because you would have changed -1
itself to 1 (not just assigned 1 to a variable that previously
referenced -1). The same would be true of this:x = -1
x.abs! # x is the immediate value -1This is also why there are no ++ and – operators in Ruby. 1++ would
mean that the actual number 1 would henceforth mean 2.
DavidWell… something++ could get expanded into (something = something.++()) ?
And ++something get expanded into (tmp = something, something =
something.++(), tmp)
Pure syntax sugar.
Then you can:
def ++()
self + 1
end
I think += does that already, doesn’t it ?
There are other reasons why there is no ++ in Ruby.
Well, I’ll take your word for it, but apparently Matz is keeping them
secret I’m just summarizing the reasons Matz has talked about in
the past (the illogic of incrementing integers, which are unique and
immutable, and which are present as immediate values in the variables
that represent them).
Of course the parser could be taught to do what you describe – it’s
just that it wouldn’t make sense. Keep in mind that these two things
are equivalent:
1++
and
x = 1
x++
so if the former makes no sense, then neither does the latter. Making
some sort of special case where, suddenly, integers are not immmediate
values strikes me as not very sugary
David
Jean-Hugues ROBERT wrote:
This is also why there are no ++ and – operators in Ruby. 1++ would
mean that the actual number 1 would henceforth mean 2.
DavidWell… something++ could get expanded into (something = something.++()) ?
And ++something get expanded into (tmp = something, something =
something.++(), tmp)
Pure syntax sugar.
Then you can:
def ++()
self + 1
end
I think += does that already, doesn’t it ?
There are other reasons why there is no ++ in Ruby.
Well, my impression is that Matz doesn’t like for assignment to be
done except where it’s painfully obvious there’s an assignment.
Assignment is not considered a true operator in Ruby. (Yes, it has
precedence, but it operates on variables, not on objects.)
But we are used to thinking of ++ and – as operators, not as
assignment.
This may be part of the reason. But IANYM.
Also IMO these operators can encourage some obfuscated code which
would be better written another way. Of course, both parts of my
statement are debatable.
Hal
About ++ & += operators…
Jean-Hugues ROBERT jean_hugues_robert@yahoo.com writes:
Well… something++ could get expanded into (something = something.++()) ?
And ++something get expanded into (tmp = something, something =
something.++(), tmp)
Pure syntax sugar.
Then you can:
def ++() self + 1 end
I think += does that already, doesn’t it ?
There are other reasons why there is no ++ in Ruby.Well, I’ll take your word for it, but apparently Matz is keeping them
secretI’m just summarizing the reasons Matz has talked about in
the past (the illogic of incrementing integers, which are unique and
immutable, and which are present as immediate values in the variables
that represent them).
That there would be other reasons does not mean that I know what
they are
Of course the parser could be taught to do what you describe – it’s
just that it wouldn’t make sense. Keep in mind that these two things
are equivalent:
1++
and
x = 1
x++
so if the former makes no sense, then neither does the latter. Making
some sort of special case where, suddenly, integers are not immmediate
values strikes me as not very sugary
David
I agree that
1 += 1
does not make much sense, yet
x = 1
x += 1
does make some sense.
I am not advocating for special cases when I assume that some kind
of lvalue exists, or am I ?
Jean-Hugues
···
At 21:59 23/04/2004 +0900, David wrote:
Jean-Hugues ROBERT said:
I agree that
1 += 1
does not make much sense, yet
x = 1
x += 1
does make some sense.
I am not advocating for special cases when I assume that some kind
of lvalue exists, or am I ?
Just like +=, ++ can not be defined as a method on an object.
But you are correct that there is no /technical/ reason preventing ++a
from being treated an abbreviation for a=a+1.
However, one must balance the advantages against the disadvantages. Does
the convenience make up for the complexity of yet more special syntax.
Does it fit well with the rest of the language? (for example: += works
well with strings, what should ++ do with strings? What should ++ do with
time values: increment by an hour, a minute, a second, a day?).
In this matter of balance, everyone will weigh the sides differently. So
far, Matz has decided that the convenience of saving one character doesn’t
balance the extra complexity involved. So be it. Many people agree, some
people dont’. I can live with that (and I’m glad it is Matz deciding and
not me!).
···
–
– Jim Weirich jim@weirichhouse.org http://onestepback.org
“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)
About ++ …
Just like +=, ++ can not be defined as a method on an object.
but + can be redefined and ++ could as well. As a matter of fact
one may argue that even ++pre and ++post could be redefined (but
I am certainly not going to advocate for that).
But you are correct that there is no /technical/ reason preventing ++a
from being treated an abbreviation for a=a+1.
I suspect that there are technical reasons. I would have to dig in
the lexer/parser code to figure out what they are I suppose.
However, one must balance the advantages against the disadvantages. Does
the convenience make up for the complexity of yet more special syntax.
Does it fit well with the rest of the language? (for example: += works
well with strings, what should ++ do with strings? What should ++ do with
time values: increment by an hour, a minute, a second, a day?).
++ is a nice idiom. I remember how happy I was when I eventually figured
it out while learning C. Remember:
strcpy( char* dest, char *src ) { while *dest++ = *src++ }
Much the same nostalgia with a->b shorthand for (*a).b !
That one will be in ruby 2 somehow: key: value for :key => value
L’histoire est un éternel recommencement.
history is an eternal rebeggining (sorry for that)
In this matter of balance, everyone will weigh the sides differently. So
far, Matz has decided that the convenience of saving one character doesn’t
balance the extra complexity involved. So be it. Many people agree, some
people dont’. I can live with that (and I’m glad it is Matz deciding and
not me!).
So do I
Jean-Hugues
···
At 03:48 24/04/2004 +0900, you wrote:
Jean-Hugues ROBERT said:
About ++ …
Just like +=, ++ can not be defined as a method on an object.
but + can be redefined and ++ could as well.
- is a method. It is sent to an object. (e.g. 1+2 === 1.+(2) )
= is not a method. It is never sent to an object. It binds objects to
names within a scope. (e.g. x=1 means that the name “x” is now bound
to the value “1”)
++ cannot be a method because it changes bindings, just like =.
See http://onestepback.org/index.cgi/Tech/Ruby/Shoeboxes.rdoc
···
At 03:48 24/04/2004 +0900, you wrote:
–
– Jim Weirich jim@weirichhouse.org http://onestepback.org
“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)
Let me rephrase.
If ruby was to understand:
this++
++that
as (syntax sugar for):
(tmp = this, this = something.postplusplus(), tmp)
(that = that.preplusplus())
then one could redefine methods postplusplus() and preplusplus()
(whose default definitions should be: self.plusplus(); in a decent world).
I understand that = is not a method as of today. And need not to
be for ++ to be re definable (as rephrased).
BTW: Making = a method (of class Binding I guess) would open
interesting perspectives…
Jean-Hugues
···
At 05:52 24/04/2004 +0900, Jim Weirich wrote:
Jean-Hugues ROBERT said:
About ++ …
At 03:48 24/04/2004 +0900, you wrote:Just like +=, ++ can not be defined as a method on an object.
but + can be redefined and ++ could as well.
- is a method. It is sent to an object. (e.g. 1+2 === 1.+(2) )
= is not a method. It is never sent to an object. It binds objects to
names within a scope. (e.g. x=1 means that the name “x” is now bound
to the value “1”)++ cannot be a method because it changes bindings, just like =.
Jean-Hugues ROBERT said:
About ++ …
Just like +=, ++ can not be defined as a method on an object.
but + can be redefined and ++ could as well.
- is a method. It is sent to an object. (e.g. 1+2 === 1.+(2) )
= is not a method. It is never sent to an object. It binds objects
to
names within a scope. (e.g. x=1 means that the name “x” is now
bound
to the value “1”)++ cannot be a method because it changes bindings, just like =.
Let me rephrase.
If ruby was to understand:
this++
++that
as (syntax sugar for):
(tmp = this, this = something.postplusplus(), tmp)
(that = that.preplusplus())
then one could redefine methods postplusplus() and preplusplus()
(whose default definitions should be: self.plusplus(); in a decent
world).I understand that = is not a method as of today. And need not to
be for ++ to be re definable (as rephrased).
IMHO, if it was decided to add ++ and – to the language, it should
be made obvious that ++ is not a method. Instead of translating var++
to var += 1, or defining a #++() method, it should replace the contents
of var with var.succ, or var.pred. It might translate something like
this:
print var++
print var–
print ++var
print --var
becomes the equivalent of:
print lambda{|tmp|tmp=var;var=var.succ;tmp}[nil]
print lambda{|tmp|tmp=var;var=var.pred;tmp}[nil]
print (var = var.succ)
print (var = var.pred)
Then all that would be needed would be to implement #succ and #pred for
any object, and you can ++ and – your heart out.
It should be pointed out out that var++ is not equivalent to var +=
1, as someone suggested. var++ returns the original value of var, then
sets it to the incremented value.
BTW: Making = a method (of class Binding I guess) would open
interesting perspectives…
!!! I really hope that was a joke!
cheers,
–Mark
···
On Apr 23, 2004, at 2:37 PM, Jean-Hugues ROBERT wrote:
At 05:52 24/04/2004 +0900, Jim Weirich wrote:
At 03:48 24/04/2004 +0900, you wrote: