Morel Xavier
Posts: 73
Nickname: masklinn
Registered: Sep, 2005
|
|
Re: Postfix Typecast Operations
|
Posted: Sep 28, 2005 7:24 AM
|
|
> > That looks the same, but the meaning is completely > > different. In what you wrote, there is no typecast, > you're > > calling the "minutes", "hours" and "years" accessors of > > Fixnum objects. > > I hear you, but I think that it looks the same and the > meaning is the same, it's just that the implementation is > different.
It does look the same indeed, but the meaning is very different, what is done in Ruby is not a cast, or a type declaration, it's the access to a reading property. Said property (2.hours) may return an "Hour" object, but it may as well return another Fixnum, or a string, or whatever the author wanted it to return.
What Christopher wants to create here is not a property of an object, but a type declaration / typecast. > > I can't think of any reason why you couldn't do it in > any > > OO language with an open class for the numerics. It > would > > just be a method on that class which constructs and > > returns another object from self. > > *Christopher humbly admits ignorance* > > Open class, what's that? Is it a class which you can add > methods to after it is defined? I guess it is
> I have heard of such > things, but I never got close to one. Which languages > support this? Is there other names for this functionality? > Well, prototyping languages probably would, Javascript does allow you to extend base types (Array.prototype.whatever = function () {} will create a new method of every Array object)
Ruby allows you to "reopen" a class whenever you want, example one would be [fixed]class MyClass attr_accessor :data def initialize @data = 5 end end
o = MyClass.new o.data > 5
class MyClass def data @data*5 end def data=(value) @data = value/5 end end
o.data > 25 o.data = 4 # o.data is an integer, 4 is too, should yield 0 o.data > 0[/fixed]
And this ability is available in Python too, though a bit more difficult to use: your class is an objet, you add a new member (method) to your class. [fixed]>>> class MyObject(object): ... def __init__(self): ... self.foo = "bar" ... >>> a = MyObject() >>> a.foo 'bar' >>> a.setFoo('b') Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'MyObject' object has no attribute 'setFoo' >>> def f(self,val): # here I create my new method as a ... self.foo = val # standalone object ... >>> MyObject.setFoo = f # and I bind it to my class >>> a.setFoo('b') >>> a.foo 'b'[/fixed]
Python doesn't allow you to extend builtin types that way though, while ruby does: [fixed]irb(main):001:0> 2.test NoMethodError: private method `test' called for 2:Fixnum from (irb):1 from :0 irb(main):002:0> class Fixnum irb(main):003:1> def test irb(main):004:2> "ok" irb(main):005:2> end irb(main):006:1> end => nil irb(main):007:0> 2.test => "ok" irb(main):008:0> [/fixed] This is very powerful as it allows for easy extension of base types, but extremely dangerous since you may get collision between modules modifying base types. Handle with care
> Previously, I always automatically dismissed the idea of > extending classes post-definition as being something > unclean, and which would lead down the road to spaghetti > code. Should I rethink this prejudice? I'm not sure it could lead to spaggethi code, in Javascript, which has quite useless base types, it's a very handy way to extend these types and have them actually do useful things (you can add slices, iterators, ... to JS' arrays that way).
The issue is when just about everyone starts doing it, you don't end with spaggethi code but you end with unreliable standard types, which is why I think that kind of extensions should be done only when necessary and should be explicitely and extensively documented.
|
|