Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
When learning other languages there is often a difference between a class method and an object method.
I know that, in Perl, the class is weak. Is there also a difference between a class method and an object method?
I know the most often used class method may be the class's new method. In Perl I can call all the methods with the package name, but not the package's object. Why is that?
The perlobj man page is helpful here:
When you call a method, the thing on the left side of the arrow is passed as the first argument to the method. That means when we call Critter->new(), the new() method receives the string "Critter" as its first argument. When we call $fred->speak(), the $fred variable is passed as the first argument to speak().
In other words, Perl doesn't make a sharp distinction between class methods and instance methods. They're differentiated by what gets passed as the first argument to the method, and if some methods don't actually happen to care about what gets passed as the first argument, then you can cheat and call them the "wrong" way.
Perl won't care. It usually doesn't.
#qwrrty's answer is a good explanation for the situation, but from comments I get the impression that even though Perl makes little distinction between object and class methods, #JackXu would like such a distinction.
If you want to make such a distinction, then the solution is to check $_[0] to see if it's an object or a string, and behave appropriately (e.g. throw an exception if an object method is called with a class name as the first parameter).
There are various method signature modules available on CPAN that make this stupidly easy to do, along the lines of:
package Foo;
method xxx (Object $self: Int $x) {
...;
}
Foo->xxx(1); # throws an error because "Foo" is not an object
I'm going to pimp my own solution for this sort of thing - Moops, which not only gives you method signatures but also keywords for class, role, etc. The particular reason for pimping it here is that thanks to its support for "multi methods", you can even create a class method and an object method with the same name as each other!
use Moops;
class Foo
{
multi method xxx (ClassName $class: Int $x) {
say "CLASS METHOD - value $x";
}
multi method xxx (Object $self: Int $x) {
say "OBJECT METHOD - value $x";
}
}
Foo->xxx(1);
my $foo = Foo->new;
$foo->xxx(2);
Related
I have a function foo which takes another function (say bar) as a parameter. Is there a way to get the function name of bar as a string inside foo?
No. See the difference between methods and functions. Methods aren't passed as parameters under the hood - they are expanded into function objects when being passed to some other method/function. These function objects are instances of anonymous, compiler-generated classes , and have no name (or, at least, being anonymous classes, have some mangled name which you could access using reflection, but probably don't need).
So, when you do:
def foo() {}
def bar(f: () => Unit) {}
bar(foo)
what actually happens in the last call is:
bar(() => foo())
Theoretically, though, you could find the name of the method that the function object you're being passed is wrapping. You could do bytecode introspection to analyze the body of the apply method of the function object f in method bar above, and conclude based on that what the name of the method is. This is both an approximation and an overkill, however.
I've had quite a dig around, and I don't think that there is. toString on the function object just says eg <function1>, and its class is a synthesised class generated by the compiler rather that something with a method object inside it that you might query.
I guess that if you really needed this there would be nothing to stop you implementing function with something that delegated but also knew the name of the thing to which it was delegating.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I was wondering why you cant use the static keyword in a class.
I know that you can use it in a struct but not in a class
Does anyone know why they choose for this?
And if so are there any advantages for letting static away?
It is a terminological bêtise. What Apple did was decide that you use static in an enum or struct and class in a class. In my view this was a very foolish decision, as they are exactly parallel to one another. Many people have posted on the dev forums suggesting that they just call them all static.
The outcome is a candidate for Occam's Razor: two phrases, e.g. static property and class property, or static method and class method, that mean exactly the same thing. And then they try to cover their tracks in the documentation by adding a third term as an umbrella, "type property" (meaning a static-or-class property) or "type method" (meaning a static-or-class method), which just makes the situation even worse.
The badness of the situation is also revealed by what you have to do in protocols: you declare a class property in a protocol and then if a struct adopts it, it calls that a static property. Same thing with a class method in a protocol; an adopting struct must call that a static method. You'd think that this alone would have told them they'd done a bad thing.
Edit: The more I think about it, the more I like the proposal put forth by newacct in a comment below. If Apple had simply used the umbrella keyword type here as part of the language, the whole problem would have been solved. We could have declarations type var, type let, type func, and this would work equally in enums, structs, classes, and protocols across the board.
From the Swift Language Guide on Methods, Apple has chosen to differentiate the syntax used, based upon the fundamental Type that you're building.
Classes declare "Type Methods" with the keyword Class. Example:
class MyClass {
class func myFunc(){ ... }
}
Structs declare "Type Methods" with the keyword Static. Example:
struct MyStruct {
static func myFunc(){ ... }
}
In both cases, crating a Type Method allows you to invoke the method without first creating an instance of the class or struct.
Whereas a non class/static function would require something like
let instance = MyClass()
instance.myFunc()
... declaring the variable as a Type Method allows something like
MyClass.myFunc()
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why to use empty parentheses in Scala if we can just use no parentheses to define a function which does not need any arguments?
Consider we have a class Foo with a method bar (which does takes no arguments and return the string "bar"). There are two ways to implement bar
The first one is
class Foo {
def bar() = "bar"
}
The second one is
class Foo {
def bar = "bar"
}
While both do basically the same, they need to be called differently, the first one like this
someFoo.bar()
and the second one
someFoo.bar
Why should I use one over the other and what's the fundamental difference?
Defining a method without arguments without parentheses implies that the method is pure (it has no side effects and doesn't depend on the state of program). Such methods cannot be called with parentheses:
class Square(val side: Int) {
def area = side * side
}
s = new Square(10);
s.area //ok
s.area() //compilation error
Calling a method without arguments with parentheses implies that the method has some side effects and a return type of Unit. A method defined with empty parentheses can be called with or without them.
class Foo {
def bar(): Unit = println("bar")
}
f = new Foo();
f.bar; //ok, bad style
f.bar(); // good
Neither of them needs to be called with parantheses. Yet def bar = "bar" is required to be called without parantheses, since the parantheses will be implied to be applied to it's result, thus in this case calling bar() will have the same effect as "bar"().
It's only a matter of convention. In my practice I've seen two:
Standard (used in the standard library and most 3rd party ones). Drop the parantheses when the method produces no side effects. Being "pure", i.e. besides not causing any side effects also not depending on the state, however is not a requirement. According to this convention your second example would be the correct one.
Scalaz. Drop the parantheses whenever there are no arguments to a method, i.e. the method may produce side effects. For example they pimp a method print without parentheses.
Bozhidar presented another convention, but, honestly, it's the first time I've been exposed to it.
I define a method inside a parametrized role that needs to create a new class at run time
using Moose::Meta::Class->create and apply that exact parametrized role to it. I am also making a new method for that role using
$new_class->meta->add_method( some_name => sub {
my ($self) = #_;
...
})
inside the sub {...} I want to access a method of the consumer class and use it for something, I have tried using $self->get_method, it didn't work, how do I do this?
Please notice that the $self inside the sub above is MooseX::Role::Parameterized::Meta::Role::Parameterizable
I also have another question, if I do this:
my $object = Moose::Meta::Class->create(
"some_type",
);
Why isn't $object of type some_type and it's some ugly MooseX::Role::Parameterized::Meta::Role::Parameterizable and how do I get to the object of type some_type?
To answer your second question, the reason is because Perl's OO doesn't allow you to add a method to just one instance of a class, so Moose has to fake it by creating a subclass with the extra method and reblessing the unique object into that subclass.
Note that, if you are doing things correctly and doing your introspection with isa, has, and/or does rather than by trying to rely on the name of the object's blessed package, this doesn't matter. The object still isa some_type, has all of some_type's attributes, and does all of some_type's roles even though it's now blessed into a package with an ugly auto-generated name.
It sounds like your underlying problem is nearly exactly what I described at this question: from within the role definition, you need to get at the class (and its meta-class) of the object or class the role is being applied to. This isn't possible from within normal roles, but it's possible through parameterized roles.
I'm not quite sure what you're trying to do here. Let's assume you have
my $new_class = Moose::Meta::Class->create('FooBar');
then $new_class is the meta object for FooBar. So, if you want to add a method to FooBar you would say
$new_class->add_method(foo => sub { … });
which would basically be the same as
FooBar->meta->add_method(foo => sub { … });
You should also probably use find_meta() from Moose::Util. This will return the correct meta object (if there is one) even if your class doesn't have a meta method or it uses it for something else.
As said, I'm not sure this answers your question.
I noticed that when you call a superclass's methods, you need to do something like this :
my $self = $class->SUPER::new();
Why isn't that:
my $self = $class->SUPER->new();
I suspect because $class->SUPER->new() would normally be the same as $class->SUPER()->new(). But there isn't a $class->SUPER() function, and its not clear what that would return.
On the other hand, $class->Foo::Bar has always been a valid way to call a method directly by full name, so making a special package-like thing — SUPER — fits in better. (I suspect that you could actually implement SUPER as a package, and maybe it historically was, I don't know)
PS: Take a look at the mro package, and $self->next::method. Also, take a look at Moose if you're going to do serious OO work in Perl.
In short, SUPER isn't a method. It's a virtual package. It's documented in perlobj under the "Method Invocation" section.
Note, however, that SUPER bases itself on the current package, not the package of the instance you used it with.
Method calls have a number of forms:
Calls method, possibly inherited:
->method()
Explicitly calls sub Package::method, whether that's in the inheritance tree or not:
->Package::method()
Explicitly calls the referred-to sub, whether that's in the inheritance tree or not:
->$coderef()
Calls the method that would have been called by __PACKAGE__->method() if there were no sub method in __PACKAGE__ (N.B. the class or object on the left of -> is irrelevant):
->SUPER::method()
Any of the above, depending on the contents of $method:
->$method()
(Legal even under use strict;.)
While the first form is the most common, it's worth learning about the others and how they work.
To add to what derobert said:
You're calling 'new' in the 'SUPER' namespace but passing it the object (or string), '$class'.
You don't have to use SUPER, as you can give the full package name of the parent (useful in cases of diamond inheritance):
sub init {
my $self = shift;
$self->ParentClass1::init();
$self->ParentClass2::init();
}