Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:62216 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 45816 invoked from network); 16 Aug 2012 07:26:18 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 16 Aug 2012 07:26:18 -0000 Authentication-Results: pb1.pair.com smtp.mail=krebs.seb@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=sebastian.krebs.berlin@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.215.170 as permitted sender) X-PHP-List-Original-Sender: krebs.seb@gmail.com X-Host-Fingerprint: 209.85.215.170 mail-ey0-f170.google.com Received: from [209.85.215.170] ([209.85.215.170:51091] helo=mail-ey0-f170.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 06/7C-08779-990AC205 for ; Thu, 16 Aug 2012 03:26:18 -0400 Received: by eaao11 with SMTP id o11so658358eaa.29 for ; Thu, 16 Aug 2012 00:26:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:x-google-sender-delegation:in-reply-to :references:date:x-google-sender-auth:message-id:subject:from:to :content-type; bh=u5FbzsI1cDQfhPuKOssm2rMRBGrBWjJPZE2L18yqWcY=; b=mLZJ3mUtEmqyVV1CdI/S2/TBpjKaGCEZ707s3WoslPnBQh4jp5PX3M7azuRbnQCWwc dBaI5H1L0xOPgjO4gLMO/SrtlwRYMuKUtBEfdQM7aKbM0UM1ND8WBaky/yGlSbLSkXWc lVgMw8BRShod8bVq3yJZYvzVFzWPNC6yWLil5Kg/nb4pDWEFdU9pqR2FlFKa0dURs4yj YYO7jZWihVYkypjgVgtTv8B6r5CAXYOFZl3SqRBH8KnPQRhZFkzPL1MfJkXo4QMtg7i4 AqNHdXV+pz5a9OxfNpGKhgrD9Y131nFcJ3NXk3XVKX9SMM9MzgyLOToUgIFTFnly1nbt 4epQ== MIME-Version: 1.0 Received: by 10.14.204.200 with SMTP id h48mr342278eeo.7.1345101974938; Thu, 16 Aug 2012 00:26:14 -0700 (PDT) Sender: sebastian.krebs.berlin@gmail.com X-Google-Sender-Delegation: sebastian.krebs.berlin@gmail.com Received: by 10.14.176.73 with HTTP; Thu, 16 Aug 2012 00:26:14 -0700 (PDT) In-Reply-To: References: Date: Thu, 16 Aug 2012 09:26:14 +0200 X-Google-Sender-Auth: Bauk7t-jrqo7VQypAGzlNZkYdOc Message-ID: To: internals@lists.php.net Content-Type: multipart/alternative; boundary=047d7b3439586722e904c75cf523 Subject: Re: [PHP-DEV] Proposal: use SomeClass::staticMethod From: krebs.seb@gmail.com (Sebastian Krebs) --047d7b3439586722e904c75cf523 Content-Type: text/plain; charset=ISO-8859-1 2012/8/15 Giedrius Dubinskas > On Wed, Aug 15, 2012 at 4:54 PM, Sebastian Krebs > wrote: > > 2012/8/15 Giedrius Dubinskas > > > >> On Wed, Aug 15, 2012 at 2:19 PM, Yahav Gindi Bar > >> wrote: > >> > On Wed, Aug 15, 2012 at 2:09 PM, Paul Dragoonis > >> wrote: > >> >> > >> >> Comments inline. > >> >> > >> >> On Wed, Aug 15, 2012 at 11:59 AM, Giedrius Dubinskas > >> >> wrote: > >> >> > Hello Internals! > >> >> > > >> >> > I'm just on and off luker here but thought I'll throw in an idea > for a > >> >> > feature I'd love to see in PHP: aliasing static methods. > >> >> > > >> >> > Syntax would look something like this: > >> >> > > >> >> > use Namespaced\SomeClass::staticMethod; > >> >> > use Some\Foo::bar as fooBar; > >> >> > > >> >> > staticMethod(); // would call > Namespaced\SomeClass::staticMethod() > >> >> > >> >> Then you're confusing the reader, they think you're calling a > >> >> function, but you're actually calling a class method. Confusion++ > >> > >> Static method essentially is a function (with elevated access to > >> containing class) so I don't see much of a problem here. > >> > > > > Don't know, how much I heard this, but: This is wrong! A function is a > > standalone construct, without _any_ sideeffects, which means, that it > will > > always return the same result, when you give it the same input. I know, > > that this is not completely true (see rand(), file related functions, or > > functions build on top of (ugh...) globals), but thats not the point > here. > > Static methods have a well defined context and state: The class they are > > defined in. This especially means, that they are explictly allowed to > have > > side effects (depending on the classes state). > > That is an interesting thought but from my point of view just becasue > static method can access static class attributes does not imply that > static methods are or should be stateful. I my opinion methods should be stateful, but thats more a "loose should", because thats an implementation detail of the method itself, which I shouldn't care about. However, even more I think, that functions _shouldn't_ have a state. There are many exceptions we all know, but I don't think it's a good reason to produce own stateful functions at will and begin to treat methods and functions as the same. > For me stateful static > methods just like stateful functions have their place (e.g. rand()) > but its very limited and should not be considered common. I don't see > how stateful static method is any better then stateful function. Other way round: Stateful functions are worse ;) > If > you could share any resources that would convince my otherwise I'd be > like to learn that. Anyway I guess we are already drifting away from > the original suggestion... :-) > > >> > >> >> > >> >> > fooBar(); // would call Some\Foo::bar() > >> >> > >> >> What if a function called staticMethod() already exists, there'd be a > >> >> bunch of confusion on referring to the right one. > >> > >> Aliased static method would be translated during compilation and no > >> additional resolution rules would be required. If one would try to > >> define a function with same name in same file as alias, that would > >> result in fatal error just like with class aliases: > >> > >> use Foo::bar as fooBar(); > >> > >> function fooBar() {} // Fatal error: Cannot redeclare ... > >> > >> >> > >> >> > > >> >> > This would make code more readable, by removing the the noise of > >> >> > repetition of class names. For use cases we can look at Java use > cases > >> >> > for "import static". > >> >> > >> >> When you find a function call, you'd have to scroll up to the top of > >> >> the page to see if it's actually a method alias. In this case being > >> >> explicit is a good thing, no scrolling, no confusion. > >> > >> As of now when we see ``fooBar()`` we already have no idea where that > >> ``fooBar`` declaration is. It may be declared in same namespace in > >> some other file, in global namespace in some other file or built in > >> function. I don't think that explicit alias in same file adds much > >> confusion to what we already have. > >> > > > > Thats wrong: "fooBar" is either in the current, or in the global > namespace, > > thats all. It's extremely easy to find out, wether or not a function is > > built-in or not (hint: Manual ;)). If it's a custom function, ok, then > you > > usually have to look at it, but I don't see, how this is a reason to make > > it even more worse by adding the possibility, that it can be a method > too. > > > > > >> > >> >> > > >> >> > Aliasing class constants like that would also be very nice. > >> >> > > >> >> > What does everyone think? > >> >> > Would it be possible in PHP? > >> >> > > >> >> > -- > >> >> > Giedrius Dubinskas > >> >> > >> >> Not that I don't welcome your suggestions, I encourage them, but for > >> >> this paritcular one I vote -1 on it. > >> >> > >> >> Thanks. > >> >> > >> >> > > >> >> > -- > >> >> > PHP Internals - PHP Runtime Development Mailing List > >> >> > To unsubscribe, visit: http://www.php.net/unsub.php > >> >> > > >> >> > >> >> -- > >> >> PHP Internals - PHP Runtime Development Mailing List > >> >> To unsubscribe, visit: http://www.php.net/unsub.php > >> >> > >> > > >> > Hi, > >> > > >> > To be honest, I'm not a fan of aliasing - and Paul supplied some of > the > >> > reasons that stands for me. > >> > When one see an class / function declaration - I think that it'll make > >> > confuse if he/she'll have to look if this is an alias or not. Besides > of > >> > that, there's still the issue of "overriding existing functions" rules > >> which > >> > can confuse the user. > >> > > >> > Put that aside, if you can bring some example of good practice it'll > be > >> > great :) > >> > >> I think a good example from top of my head would be PHPUnit testing > >> framework. It has class PHPUnit_Framework_Assert that contains only > >> static assertion methods like assertEquals(), assertTrue(), etc. Then > >> it has class PHPUnit_Framework_TestCase that extends > >> PHPUnit_Framework_Assert. > >> > >> AFAICT there is no other reason for this hierarchy except to allow > >> shorter assertion syntax. Example from PHPUnit manual: > >> > >> require_once 'PHPUnit/Framework.php'; > >> > >> class MessageTest extends PHPUnit_Framework_TestCase > >> { > >> public function testMessage() > >> { > >> $this->assertTrue(FALSE, 'This is a custom message.'); > >> } > >> } > >> > >> What is more PHPUnit_Framework_TestCase also contains methods > >> dedicated for mocking like once(), returnValue(), etc. Another > >> example: > >> > >> class StubTest extends PHPUnit_Framework_TestCase > >> { > >> public function testReturnArgumentStub() > >> { > >> // Create a stub for the SomeClass class. > >> $stub = $this->getMock('SomeClass'); > >> > >> // Configure the stub. > >> $stub->expects($this->once()) > >> ->method('doSomething') > >> ->with($this->lessThen('something')) > >> ->will($this->returnValue(true)); > >> > >> $this->assertTrue($stub->doSomething('foo')); > >> $this->assertTrue($stub->doSomething('bar')); > >> } > >> } > >> > >> Note that PHPUnit manual promotes using $this despide the fact that > >> these methods are ``public static``. > >> > >> I think assertions and mocking could be decoupled and would be more > >> readable like this: > >> > >> use PHPUnit_Framework_Assert::assertTrue; > >> use PHPUnit_Framework_Assert::lessThen; > >> use PHPUnit_Framework_MockObject_Matcher::once; > >> use PHPUnit_Framework_MockObject_Matcher::returnValue; > >> > >> class StubTest extends PHPUnit_Framework_TestCase > >> { > >> public function testReturnArgumentStub() > >> { > >> // Create a stub for the SomeClass class. > >> $stub = $this->getMock('SomeClass'); > >> > >> // Configure the stub. > >> $stub->expects(once()) > >> ->method('doSomething') > >> ->with(lessThen('something')) > >> ->will(returnValue(true)); > >> > >> assertTrue($stub->doSomething('foo')); > >> assertTrue($stub->doSomething('bar')); > >> } > >> } > >> > > > > This means, this is once more a "I want to save characters in my code"? > If > > you ask me: > > > > - assert*() could be _real_ functions. > > > > function assert\tue($arg, $msg) { > > $arg or throw new AssertionException($msg); > > } > > This would still require some kind of namespace prefix. It may work > with ``assert\isTrue`` or something like that but it's not so > straightforward with mocking example above. > I don't have any problem with namespaces, I like, how the tell me, where something is coming from. Because you mentioned your mocking-example: There you have the function 'assertTrue()'. 'assert*()' is just a prefix here, what reminds me of all the good all functions like strpos() and such. Do you think this is _really_ better? And where is the ugly difference between 'assert\isTrue()' and 'assertTrue()'? I like the namespaced version more, because 'assert' is not just a prefix telling me, what "kind" of function that is, it is more an indicator to which "family" it belongs to. > > > - assert*() could be methods within _a trait_ (to decouple it from the > > TestCase-class) > > > > class StubTest extends PHPUnit_Framework_TestCase { > > use Assertion\Boolean; > > > > public function testReturnArgumentStub() > > { > > $this->assertTrue(true); > > // or? > > self::assertTrue(true); > > } > > } > > This does not add anything to readability. This is just the same it is now. > Must say: Don't know, how unreadable it really is... Even with your mocking example. > > > Not, that I want to rewrite PHPUnit (maybe I should suggest it Sebastian > > Bergman for a (very) future release? :3). > > > > > > tl;dr: The problem I have with this suggestion is, that I don't get, want > > you want to solve and/or to win. > > My main aim with this suggestion is readability. I'd like to remove > unnecessary noise in code where it doesn't add any value to the > reader. Code is easy to type (especially with good autocompletion) but > it is read more often then typed and I think that is important. Or is > it just me? > You are right, that code is read more often, than write, but thats exactly, why "clarity" is part of "readabilit". Do you always need to read the whole source (especially the head) just to find out wether foo() is a function, or a method? Ambiguity is not good for readability. > > -- > Giedrius Dubinskas > --047d7b3439586722e904c75cf523--