What is the significance of 'static' in a method - class

Looking at the addValues method below, this is not callable if I don't include the 'static' keyword. Why is this so?
namespace TryingMethods
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(addValues(3, 4));
}
public static int addValues(int left, int right)
{
return left + right;
}
}
}

It's because static method can only have acces to static variables and other static methods. Normally, you cannot call addValues(int left, int right) inside main() method which is static. Only way around is to have an instance of a class containing addValues() method.

When you do not say static , it means that the method is a 'property' of the object, which is an instantiation of this particular class. When you do not say static, it means that the method is not a property of the object, and thus, can be called without referring to the object.
For example, you could have a Person class, and there is a static method "Print hello" and there is a non-static method "Give me name". Printing hello is not relevant to the particular person, so it is static. "Give me name" is relevant to the particular person, so you need to call this method differently.
Person myMan = new Person();
myMan.giveMeName();
printHello();

You don't need to instanciate the class in order to call static methods.
Program.addValues(1,2)
static methods can't get/set class members

It's because you have your Main function declared as static, so the methods that you call in it need to be too. If you remove static from both you wouldn't get the error.

Related

Non-static method cannot be called statically [duplicate]

Im trying to load my model in my controller and tried this:
return Post::getAll();
got the error Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context
The function in the model looks like this:
public function getAll()
{
return $posts = $this->all()->take(2)->get();
}
What's the correct way to load the model in a controller and then return it's contents?
You defined your method as non-static and you are trying to invoke it as static. That said...
1.if you want to invoke a static method, you should use the :: and define your method as static.
// Defining a static method in a Foo class.
public static function getAll() { /* code */ }
// Invoking that static method
Foo::getAll();
2.otherwise, if you want to invoke an instance method you should instance your class, use ->.
// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }
// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();
Note: In Laravel, almost all Eloquent methods return an instance of your model, allowing you to chain methods as shown below:
$foos = Foo::all()->take(10)->get();
In that code we are statically calling the all method via Facade. After that, all other methods are being called as instance methods.
Why not try adding Scope? Scope is a very good feature of Eloquent.
class User extends Eloquent {
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeWomen($query)
{
return $query->whereGender('W');
}
}
$users = User::popular()->women()->orderBy('created_at')->get();
Eloquent #scopes in Laravel Docs
TL;DR. You can get around this by expressing your queries as MyModel::query()->find(10); instead of MyModel::find(10);.
To the best of my knowledge, starting PhpStorm 2017.2 code inspection fails for methods such as MyModel::where(), MyModel::find(), etc (check this thread), and this could get quite annoying.
One (elegant) way to get around this is to explicitly call ::query() wherever it makes sense to. This will let you benefit from free auto-completion and a nice formatting/indentating for your queries.
Examples
BAD
Snippet where inspection complains about static method calls
// static call complaint
$myModel = MyModel::find(10);
// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_foo', true)
->where('is_bar', false)
->get();
GOOD
Well formatted code with no complaints
// no complaint
$myModel = MyModel::query()->find(10);
// a nicely formatted and indented query with no complaints
$myFilteredModels = MyModel::query()
->where('is_foo', true)
->where('is_bar', false)
->get();
Just in case this helps someone, I was getting this error because I completely missed the stated fact that the scope prefix must not be used when calling a local scope. So if you defined a local scope in your model like this:
public function scopeRecentFirst($query)
{
return $query->orderBy('updated_at', 'desc');
}
You should call it like:
$CurrentUsers = \App\Models\Users::recentFirst()->get();
Note that the prefix scope is not present in the call.
Solution to the original question
You called a non-static method statically. To make a public function static in the model, would look like this:
public static function {
}
In General:
Post::get()
In this particular instance:
Post::take(2)->get()
One thing to be careful of, when defining relationships and scope, that I had an issue with that caused a 'non-static method should not be called statically' error is when they are named the same, for example:
public function category(){
return $this->belongsTo('App\Category');
}
public function scopeCategory(){
return $query->where('category', 1);
}
When I do the following, I get the non-static error:
Event::category()->get();
The issue, is that Laravel is using my relationship method called category, rather than my category scope (scopeCategory). This can be resolved by renaming the scope or the relationship. I chose to rename the relationship:
public function cat(){
return $this->belongsTo('App\Category', 'category_id');
}
Please observe that I defined the foreign key (category_id) because otherwise Laravel would have looked for cat_id instead, and it wouldn't have found it, as I had defined it as category_id in the database.
You can give like this
public static function getAll()
{
return $posts = $this->all()->take(2)->get();
}
And when you call statically inside your controller function also..
I've literally just arrived at the answer in my case.
I'm creating a system that has implemented a create method, so I was getting this actual error because I was accessing the overridden version not the one from Eloquent.
Hope that help?
Check if you do not have declared the method getAll() in the model. That causes the controller to think that you are calling a non-static method.
For use the syntax like return Post::getAll(); you should have a magic function __callStatic in your class where handle all static calls:
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}

Can I add a method on es6 class after it is defined?

Method
method() {}
function
function func() {}
Above is just to elaborate difference between method and function.
class Student {
constructor(name, age) {
this.name = name;
this.age = age;
}
method1(){}
}
In the above class, after writing the definition.
I want to add a method2 to the class, similar to the way method1 is there.
I can add a function like soo
Student.prototype.func = function(){...}
But I do not have a way to add a method on the same class. and inside function I will not be able to use super as that is just available inside the method.
Is there a way I can add method after the class is defined ?
So that I will be able to use super inside that.
As has already been explained, you can only use super() inside the regular class definition. But, long before we had ES6, we were calling parent method implementations manually. It can be done using the parent's prototype:
class Person {
talk() {
// some implementation here
}
}
class Student extends Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
Student.prototype.talk = function(data) {
// now call base method manually
Person.prototype.talk.call(this, data);
// then do our extra work
log(data);
}
Of course, normally you could just declare all your methods within the class declaration so this would not be something you would normally need to do.
Your snippet adding a new property to the prototype is only approach for adding a function later. One main difference in this case is that simple assignment like that will create the property as enumerable by default, whereas class syntax would create is as non-enumerable. You could use
Object.defineProperty(Student.prototype, "func", {
configurable: true,
writable: true,
value: function() {
},
});
to address that at least.
Unfortunately as you've seen, adding things to the prototype afterward does not allow usage of super.foo. There is no way for this to be supported, because the behavior of super is based specifically on the lexical nesting of the method syntax method(){} being inside of the class syntax. Methods added programmatically later on would have no way to know which prototype is the "super" one.

How to get current class name/object inside PowerShell static class method?

I need $this to work inside static class! How to achieve that? Any workaround? I have analyzed return of Get-PSCallStack in class context and found nothing useful.
I need this for (a) logging and for (b) calling other static methods of same class without mentioning its name again and again.
Sample code (PowerShell v5):
class foo {
static [void]DoSomething() {
[foo]::DoAnything() #works
#$this.DoAnything #not working
$static_this = [foo]
$static_this::DoAnything() #works
}
static [void]DoAnything() {
echo "Done"
}
}
[foo]::DoSomething()
Static classes do not have this pointer. See MSDN
Static member functions, because they exist at the class level and not
as part of an object, do not have a this pointer. It is an error to
refer to this in a static method.
You must call method by class name.

How to add a call to a non-static class member function to the threadpool?

I'm looking for this stackoverflow: How to get Windows thread pool to call class member function? for C++/CLI:
I have a ref class with a member function (a copy of that function is static for testing purposes):
ref class CTest
{
public:
static void testFuncStatic( System::Object^ stateInfo )
{
// do work;
}
void testFunction( System::Object^ stateInfo )
{
// do work;
}
};
From main() I can easily add a call to the static function to the threadpool:
System::Threading::ThreadPool::QueueUserWorkItem (gcnew System::Threading::WaitCallback (&CTest::testFuncStatic));
But I don't want to call the static function (which is more or less an object-independent global function), I want to call the member function testFunction() for several instances of the class CTest.
How can I achieve that?
In C++/CLI, you need to explicitly specify the object you want the delegate to call the function on.
ThreadPool::QueueUserWorkItem(gcnew WaitCallback(this, &CTest::testFunction));
^^^^
You should not use thread pools in .NET. You should consider to use System::Threading::Tasks. This is an even more efficient way to use multiple "Tasks"...
Also be aware of the new "async" keyword in C#4.5. This helps a lot! So you should really consider to put the .NET part of your application into C#... and only use C++/CLI for InterOp scenarios.
Try this:
CTest ^ ctest = gcnew CTest;
ThreadPool::QueueUserWorkItem(gcnew WaitCallback(ctest, &CTest::testFunction));
^^^^^
WaitCallback(ctest provides memory context to allocated object of CTest
&CTest::testFunction)); provides memory shift to actual allocated function memory address of testFunction.
'Dynamic' functions are part of 'dynamic' class object.
This must be like that because of garbage collector.

Calling a public method

I'm trying to figure out how to centralize a method that I use in a few of my ViewControllers. I already had a singleton that I was using for some variables. I called the singleton class Shared.
I moved my method to the Shared class and tried calling it like so:
m.createdAt = [Shared getUTCFormateDate:[messageObject objectForKey:#"created_at"]];
It's giving me an exception saying that the selector doesn't exist when it tries to call it.
I have already imported Shared.h. Any other thoughts would be appreciated.
If your class is named "Shared" then it looks like you are trying to call a class method rather than an instance method. So, you need to declare the method with + instead of -.
here is the correct pattern for creating a Singleton in objective-c: (Ill use an example of a User object.. taken from code I have open in front of me). also, please note that there is a difference between Singleton classes and Static Class methods, as discussed here.. Difference between static class and singleton pattern?
in the .h file, declare a static method that returns an instance of your class.
+(User *) currentUser;
in the .m file, create a static variable that holds your instance
static User * _user;
then, in your .m class, create your "public" static accesor GET that returns or instantiates and returns your static variable
+ (User *) currentUser
{
if (!_user)
{
_user =[[User alloc]init];
// ... init the singleton user properties and what not
// ...
}
return _user;
}
then, when you want to call on your Singleton class you just make sure that User.h is imported and call [[User currentUser] someMethodorProperty];
enjoy