What’s this syntax, z = Complex(1,2), as opposed to z =
Complex.new(1,2)? How do I imitate this behavior in my own classes?
On Thu, Mar 29, 2012 at 3:26 PM, Ori Ben-Dor [email protected]
wrote:
What’s this syntax, z = Complex(1,2), as opposed to z =
Complex.new(1,2)? How do I imitate this behavior in my own classes?
It’s a method in Kernel (which is included into Object, and so you can
use it anywhere):
Jesus.
I see, thanks.
But why would this be the way to create new instances of class Complex,
instead of through a constructor in class Complex itself?
I’d add that, while this works, you better have a very good reason for
doing so - it breaks convention.
–
Da: “Jan E.” [email protected]
A: [email protected]
Cc:
Data: Thu, 29 Mar 2012 23:00:57 +0900
Oggetto: Re: Why z = Complex(1,2) rather than z = Complex.new(1,2)?
Well, I don’t have a very good reason, but it doesn’t seem whoever wrote
Kernel and Complex had a good reason as well…
Hi,
You can define upper-case methods, but when you call them, you always
have to use parenthesis so that Ruby doesn’t confuse them with
constants:
def Hallo
puts ‘Hallo Welt!’
end
Hallo()
However, this violates the naming conventions of Ruby, so you shouldn’t
do it. Why not define a [] method?
class MyClass
def initialize value
@value = value
end
attr_reader :value
def self.[] value
new value
end
end
a = MyClass[4]
puts a.value
Ori Ben-Dor wrote in post #1053937:
I see, thanks.
But why would this be the way to create new instances of class Complex,
instead of through a constructor in class Complex itself?
Well, this really doesn’t fit into Ruby. I guess those are meant to be
special built-in methods. Personally, I have never used them.
Ori Ben-Dor wrote in post #1053937:
But why would this be the way to create new instances of class Complex,
instead of through a constructor in class Complex itself?
It’s a convenience method which saves 4 characters (".new") and also
looks nicer (although that lies in the eye of the beholder). Complex()
is just an ordinary method. There are more of them, for example
Integer() as well which is a safe version of String#to_i.
Kind regards
robert
But doesn’t it break the convention? I mean, the convention is using a
constructor, so what’s special about Complex that justifies breaking it?
If the saving four characters argument is valid for Complex, why isn’t
valid for all classes in general?
Ori Ben-Dor wrote in post #1053971:
But doesn’t it break the convention? I mean, the convention is using a
constructor,
No, there is no such convention. Using class.new is the basic way to
create an instance but nothing forbids having methods which return new
instances. In fact, it happens all the time. The only thing that is
unusual here is that the method “coincidentally” has the same name as
the class of the instances it returns.
so what’s special about Complex that justifies breaking it?
If the saving four characters argument is valid for Complex, why isn’t
valid for all classes in general?
Because Complex is a numeric type and it can be called “basic” with
enough justification, I guess.
Cheers
robert
On Mar 29, 2012, at 8:31 AM, Ori Ben-Dor wrote:
But doesn’t it break the convention?
I’ve never heard that there was a convention to avoid capitalizing
method names, and I’ve been doing this a long time. It just so happened
that almost nobody bothered to.
Now, the convention is to provide a type conversion method that matches
your class name for convenience.
I mean, the convention is using a constructor, so what’s special about Complex
that justifies breaking it?
We decided to do something different because it was useful and looks
nice.
If the saving four characters argument is valid for Complex, why isn’t valid for
all classes in general?
Looking at ri Kernel
I see the following type-conversion methods:
Array
BigDecimal
Complex
Float
Integer
JSON
Pathname
Rational
String
URI
So, if you have your own class, there’s a precedent for adding your own
type conversion method to Kernel.
Eric H. wrote in post #1054029:
I’ve never heard that there was a convention to avoid capitalizing
method names, and I’ve been doing this a long time.
This convention is in the Ruby book by Matz and Flanagan, saying that
uppercase method names can be confused with constants (which is a bad
thing in my opion).
So it’s not that we made this up.
In Netbeans I even get a warning:
“Style: Method names traditionally use lowercase letters only”
But it’s not so much about conventions. These methods are simply
counterintuitive. When I want to convert objects, the first thing that
comes to my mind are the to_… methods. But I don’t expect someone to
pull a magical conversion “function” out of the Kernel module. Honestly,
I think even experienced Ruby programmers are confused when they first
see something like Float(4)
Another problem is that constants and methods have different lookup
algorithms, which doesn’t allow you to put the conversion method for a
subclass into the same containing module/class (unless you use qualified
names all the time).
All in all, I think those methods really qualify as “Ruby warts” and
should be removed as soon as possible.
Robert K. wrote in post #1054170:
Do you get that at the calling site or at the definition site?
I get the message when I define the method.
Robert K. wrote in post #1054170:
Jan E. wrote in post #1054047:
Another problem is that constants and methods have different lookup
algorithms, which doesn’t allow you to put the conversion method for a
subclass into the same containing module/class (unless you use qualified
names all the time).Can you show an example of what you cannot do? At the moment I don’t
see the limitation.
As long as you’re on top level, you can define a class and the
corresponding method on the same level:
A = Class.new
def A()
A.new
end
p A
p A()
But when the class is inside a module, you cannot define the method in
this module and access it in the same way as you access the class:
module M
A = Class.new
def self.A()
A.new
end
class B
def test
p A # this works
p A() # this doesn’t
end
end
end
b = M::B.new
b.test
Of course, there’s nothing strange about this behaviour. Methods simply
cannot access “outer methods”. But in this context, I find the different
lookup algorithms counterintutive. You’d have to qualify the method name
or define it in a different place (like the top level).
Robert K. wrote in post #1054170:
There are far worse “warts” as you call them, for example class
variables.
Sure.
Jan E. wrote in post #1054047:
Eric H. wrote in post #1054029:
I’ve never heard that there was a convention to avoid capitalizing
method names, and I’ve been doing this a long time.This convention is in the Ruby book by Matz and Flanagan, saying that
uppercase method names can be confused with constants (which is a bad
thing in my opion).
Well, but there are only few cases of this plus in this case Complex()
and Complex actually mean the same thing.
So it’s not that we made this up.
Everything should be taken with a grain of salt.
In Netbeans I even get a warning:
“Style: Method names traditionally use lowercase letters only”
Do you get that at the calling site or at the definition site?
But it’s not so much about conventions. These methods are simply
counterintuitive. When I want to convert objects, the first thing that
comes to my mind are the to_… methods. But I don’t expect someone to
pull a magical conversion “function” out of the Kernel module. Honestly,
I think even experienced Ruby programmers are confused when they first
see something like Float(4)
No, not at all. An experienced Ruby programmer will identify this
immediately as a method call. And he will probably do
~$ ruby19 -e ‘p method(:Float)’
#<Method: Object(Kernel)#Float>
And then do
ri19 Kernel#Float
But you do not have to use that method.
Another problem is that constants and methods have different lookup
algorithms, which doesn’t allow you to put the conversion method for a
subclass into the same containing module/class (unless you use qualified
names all the time).
Can you show an example of what you cannot do? At the moment I don’t
see the limitation.
All in all, I think those methods really qualify as “Ruby warts” and
should be removed as soon as possible.
There are far worse “warts” as you call them, for example class
variables.
Kind regards
robert
Jan E. wrote in post #1054185:
Robert K. wrote in post #1054170:
Do you get that at the calling site or at the definition site?
I get the message when I define the method.
That’s how it should be, so one can use Complex et al. without the
warning.
Robert K. wrote in post #1054170:
Jan E. wrote in post #1054047:
Another problem is that constants and methods have different lookup
algorithms, which doesn’t allow you to put the conversion method for a
subclass into the same containing module/class (unless you use qualified
names all the time).Can you show an example of what you cannot do? At the moment I don’t
see the limitation.
But when the class is inside a module, you cannot define the method in
this module and access it in the same way as you access the class:module M
A = Class.new
def self.A()
A.new
endclass B
def test
p A # this works
p A() # this doesn’t
end
end
endb = M::B.new
b.testOf course, there’s nothing strange about this behaviour. Methods simply
cannot access “outer methods”. But in this context, I find the different
lookup algorithms counterintutive. You’d have to qualify the method name
or define it in a different place (like the top level).
Right. Thanks for the example! I agree, that’s not intuitive. But
given that there are just a few uppercase methods which are intended as
convenience for users and are mostly (only?) defined in the core lib it
doesn’t bother me too much.
Kind regards
robert