2015年12月25日 星期五

五種開源授權規範的比較 (BSD, Apache, GPL, LGPL, MIT)

當Adobe、Microsoft、Sun等一系列巨頭開始表現出對"開源"的青睞時,"開源"的時代即將到來!

現今存在的開源協議很多,而經過Open Source Initiative組織通過批准的開源協議目前有58種(http://www.opensource.org/licenses/alphabetical)。我們在常見的開源協議如BSD, GPL, LGPL,MIT等都是OSI批准的協議。如果要開源自己的代碼,最好也是選擇這些被批准的開源協議。

這裡我們來看四種最常用的開源協議及它們的適用範圍,供那些準備開源或者使用開源產品的開發人員/廠家參考。

BSD開源協議(original BSD license、FreeBSD license、Original BSD license)


BSD開源協議是一個給於使用者很大自由的協議。基本上使用者可以"為所欲為",可以自由的使用,修改源代碼,也可以將修改後的代碼作為開源或者專有軟件再發佈。

但"為所欲為"的前提當你發佈使用了BSD協議的代碼,或則以BSD協議代碼為基礎做二次開發自己的產品時,需要滿足三個條件:

如果再發佈的產品中包含源代碼,則在源代碼中必須帶有原來代碼中的BSD協議。
如果再發佈的只是二進制類庫/軟件,則需要在類庫/軟件的文檔和版權聲明中包含原來代碼中的BSD協議。
不可以用開源代碼的作者/機構名字和原來產品的名字做市場推廣。
BSD 代碼鼓勵代碼共享,但需要尊重代碼作者的著作權。BSD由於允許使用者修改和重新發佈代碼,也允許使用或在BSD代碼上開發商業軟件發佈和銷售,因此是對 商業集成很友好的協議。而很多的公司企業在選用開源產品的時候都首選BSD協議,因為可以完全控制這些第三方的代碼,在必要的時候可以修改或者二次開發。

Apache Licence 2.0(Apache License, Version 2.0、Apache License, Version 1.1、Apache License, Version 1.0)


Apache Licence是著名的非盈利開源組織Apache採用的協議。該協議和BSD類似,同樣鼓勵代碼共享和尊重原作者的著作權,同樣允許代碼修改,再發佈(作為開源或商業軟件)。需要滿足的條件也和BSD類似:

需要給代碼的用戶一份Apache Licence
如果你修改了代碼,需要再被修改的文件中說明。
在延伸的代碼中(修改和有源代碼衍生的代碼中)需要帶有原來代碼中的協議,商標,專利聲明和其他原來作者規定需要包含的說明。
如果再發佈的產品中包含一個Notice文件,則在Notice文件中需要帶有Apache Licence。你可以在Notice中增加自己的許可,但不可以表現為對Apache Licence構成更改。
Apache Licence也是對商業應用友好的許可。使用者也可以在需要的時候修改代碼來滿足需要並作為開源或商業產品發佈/銷售。

GPL(GNU General Public License)


我們很熟悉的Linux就是採用了GPL。GPL協議和BSD, Apache Licence等鼓勵代碼重用的許可很不一樣。GPL的出發點是代碼的開源/免費使用和引用/修改/衍生代碼的開源/免費使用,但不允許修改後和衍生的代 碼做為閉源的商業軟件發佈和銷售。這也就是為什麼我們能用免費的各種linux,包括商業公司的linux和linux上各種各樣的由個人,組織,以及商 業軟件公司開發的免費軟件了。

GPL協議的主要內容是只要在一個軟件中使用("使用"指類庫引用,修改後的代碼或者衍生代碼)GPL 協議的產品,則該軟件產品必須也採用GPL協議,既必須也是開源和免費。這就是所謂的"傳染性"。GPL協議的產品作為一個單獨的產品使用沒有任何問題, 還可以享受免費的優勢。

由於GPL嚴格要求使用了GPL類庫的軟件產品必須使用GPL協議,對於使用GPL協議的開源代碼,商業軟件或者對代碼有保密要求的部門就不適合集成/採用作為類庫和二次開發的基礎。

其它細節如再發佈的時候需要伴隨GPL協議等和BSD/Apache等類似。

LGPL(GNU Lesser General Public License)


LGPL是GPL的一個為主要為類庫使用設計的開源協議。和GPL要求任何使用/修改/衍生之GPL類庫的的軟件必須採用GPL協議不同。LGPL允許商 業軟件通過類庫引用(link)方式使用LGPL類庫而不需要開源商業軟件的代碼。這使得採用LGPL協議的開源代碼可以被商業軟件作為類庫引用並發布和 銷售。

但是如果修改LGPL協議的代碼或者衍生,則所有修改的代碼,涉及修改部分的額外代碼和衍生的代碼都必須採用LGPL協議。因此LGPL協議的開源代碼很 適合作為第三方類庫被商業軟件引用,但不適合希望以LGPL協議代碼為基礎,通過修改和衍生的方式做二次開發的商業軟件採用。

GPL/LGPL都保障原作者的知識產權,避免有人利用開源代碼複製並開發類似的產品

MIT(MIT)


MIT是和BSD一樣寬範的許可協議,作者只想保留版權,而無任何其他了限制.也就是說,你必須在你的發行版裡包含原許可協議的聲明,無論你是以二進制發佈的還是以源代碼發佈的.

reference : http://inspiregate.com/internet/trends/74-comparison-of-five-kinds-of-standard-open-source-license-bsd-apache-gpl-lgpl-mit.html

2015年12月10日 星期四

Placeholders.js

Placeholders.js is a JavaScript polyfill for the HTML5 placeholder attribute. It's lightweight, has zero dependencies and works in pretty much any browser you can imagine.


reference : http://jamesallardice.github.io/Placeholders.js/

2015年12月9日 星期三

Trick to use static variables in javascript

Maybe people that have background in C language know how to do this because in C language there is a static keyword to declare a static variable. What is about Javascript?

Well, Javascript doesn't have static keyword. One way to solve this problem, you may use global variable. However, for some people, it will pollute the global namespace. Last night, I read a javascript book, Javascript - The Definitive Guide, 5th edition. The author used closure to achieve this by returning back the anonymous function.


var uniqueID = (function() {
   var id = 0; // This is the private persistent value
   // The outer function returns a nested function that has access
   // to the persistent value.  It is this nested function we're storing
   // in the variable uniqueID above.
   return function() { return id++; };  // Return and increment
})(); // Invoke the outer function after defining it.



uniqueID(); // 0

uniqueID(); // 1
uniqueID(); // 2

reference : http://chamnapchhorn.blogspot.tw/2008/07/trick-to-use-static-variables-in.html

2015年12月7日 星期一

PHPUnit - Serialization of Closure is not allowed

The answer to your literal question "Why does PHPUnit interfere with setting HTTP headers in this code?" is given fairly clearly in the answer to Test PHP headers with PHPunit. PHP's header() will fail with the Cannot modify header information warning if anything has been written to stdout. When running your code via PHPUnit, content has been sent to stdout long before your code under test has been reached.
You noted a separate issue when using the @runInSeparateProcess annotation to fork a clean PHP process for your test:
Unexpected non-MediaWiki exception encountered, of type "Exception", exception 'Exception' with message 'Serialization of 'Closure' is not allowed' in /usr/share/pear/PHPUnit/Util/GlobalState.php:354
By default PHPUnit attempts to backup all of the $GLOBALS data before each test and restore it afterwards. MediaWikiTestCase turns this behavior off but it looks like your extension's tests are not. It seems likely that the configuration for your extension includes a closure and is causing the serialization failure. Adding a @backupGlobals disabled annotation to your PHPUnit_Framework_TestCase class should get you past this problem.

reference : http://stackoverflow.com/questions/20076467/why-does-phpunit-interfere-with-setting-http-headers-in-this-code

2015年12月1日 星期二

Mockery: returning values and throwing exceptions

Last week, I had to wrote a piece of code that contains retry logic. Naturally, I want to test it. That proved trickier than expected.
The application code looks like this:
    class Sender
    {
        protected $connection;

        public function send()
        {
            $success = false;

            $i = 0;
            do {
                $i++;

                try {
                    $success = $this->doSend($i);
                } catch (SenderException $e) {
                    $success = false;
                }

            } while (!$success && $i < 3);

            return $success;
        }

        protected function doSend($data)
        {
            // Can throw SenderException
            $response = $this->connection->send($data);

            if ('OK' === $response) {
                return true;
            }

            return false;
        }
    }

I specifically want to test the retry logic, so I have to mock the ::doSend() method. Then I can simulate the different outcomes (returning true or false, or throwing a SenderException).
I use Mockery to do the real work. It is a great library. If you don't know it yet, please check it out. I will wait right here...
Now, since ::doSend() is a protected method, Mockery must be instructed to allow that.
So after the first try, I ended up with:
    public function testItWillRetrySending()
    {
        $sender = M::mock('Sender');
        $sender->shouldAllowMockingProtectedMethods()

        $sender->shouldReceive('doSend')
            ->andReturn(false, new Exception());
    }

To my surprise, this did not work. Instead of throwing the exception, Mockery returns it. So my next try was this:
    $sender->shouldReceive('doSend')
        ->andReturn(false)
        ->andThrow(new Exception());
Another surprise: with this code, Mockery will always throw the exception, and ignore the first return value (false). After some debugging, I found out that Mockery just overwrites the return values in this case.
Fortunately, there is another way to return multiple return values: the ::andReturnUsing() method. It gives full control over the return values.
So I ended up with this testing code:
    $return_value_generator = function () {
        static $counter = 0;

        $counter++;

        switch ($counter) {
            case 1: return false;
            case 2: throw new SenderException();
            case 3: return true;
            default: throw new Exception("Should never reach this."); 
        }
    };

    $sender = M::mock('Sender');

    $sender->shouldAllowMockingProtectedMethods()
        ->shouldReceive('doSend')
        ->andReturnUsing($return_value_generator);

This works perfectly. It feels a bit like a hack though. So if you know a better way or have any other remarks, please let me know.

refer : https://jacobkiers.net/post/multiple-return-values-with-mockery

2015年11月27日 星期五

The reason why singleton is a “problem” with PHPUnit

So we add to our test:
1
2
3
4
5
6
7
8
class FooTest extends PHPUnit_Framework_TestCase
{
...
    public function tearDown()
    {
        Foo::tearDown();
    }
}
And now we implement the tearDown function in our Foo Class

1
2
3
4
public static function tearDown()
{
    static::$instance = NULL;
}

refer : http://gonzalo123.com/2012/09/24/the-reason-why-singleton-is-a-problem-with-phpunit/

2015年11月24日 星期二

Debug Your App with the Laravel Debugbar

Debug Your App with the Laravel Debugbar

The Laravel Debugbar by Barry vd. Heuvel is a package that allows you to quickly and easily keep tabs on your application during development. With a simple installation and powerful features, theDebugbar package is one of the cornerstone packages for Laravel.
The debugbar is already updated for Laravel 5 and I wanted to show you all the great features it includes.

Installing the Laravel Debugbar

Installation is extremely simple. I was about to have it running in under five minutes, and four of those was waiting on composer. Here are the steps to get it setup and going.
In your Laravel 5 project require the package:
composer require barryvdh/laravel-debugbar
Next open config/app.php and inside the ‘providers’ array add:
'Barryvdh\Debugbar\ServiceProvider',
Finally, if you wish to add the facades add this to the ‘aliases’ array:
'Debugbar' => 'Barryvdh\Debugbar\Facade',
Now as long as your app is in debug mode the bar will already be loading showing some nice stats about the page you are viewing.

Getting to know debugbar

You have the user interface of the debugbar mastered in a few short minutes and it’s really powerful. Let’s look at all the default settings that are included:
Messages
debugbar-messages
Messages is a special section, it’s only loaded by calling the facade from within your code.
Debugbar::info($object);
Debugbar::error('Error!');
Debugbar::warning('Watch out…');
Debugbar::addMessage('Another message', 'mylabel');
The messages include the PSR-3 levels (debug, info, notice, warning, error, critical, alert, emergency)
Timeline
debugbar-timeline
The timeline is perfect for fixing the bottlenecks in your code. Here are a few examples available:
Debugbar::startMeasure('render','Time for rendering');
Debugbar::stopMeasure('render');
Debugbar::addMeasure('now', LARAVEL_START, microtime(true));
Debugbar::measure('My long operation', function() {
// Do something…
});
Exceptions
debugbar-exceptions
The next tab is an exceptions logger. You can log exceptions to the debugbar by using code like this:
try {
  throw new Exception('foobar');
} catch (Exception $e) {
  Debugbar::addException($e);
}
Views
Laravel debugbar views
Views will show you all the templates rendered as well as include all the parameters passed into them. This is really handy as your application grows and you have numerous views. With this, you can be sure you are sending just the data your view actually needs, and lots of other use cases.
Route
Laravel Debugbar Route
Magically see everything related to the route being called. The URI, controller, file path, and namespace.
Queries
Laravel Debugbar Queries
Queries are one of the important parts for a lot of apps. I’ve seen apps not utilize eager loading and end up with a huge number of queries.
To give you a real world example I was tasked with building a back office style report for an e-commerce system. I was able to get the report working on my dev machine with seed data but as soon as I seeded real data the page took 20+ seconds to load. Browsing the queries tab in debugbar showed me exactly where my problem was.
Mail and Request
These two include everything you need to know about emails going out and the current request.
Folder Icon
Laravel Debubar Open
I’m not sure the “real” name for this, but by clicking the folder icon you can see all previous requests. This is useful when performing ajax calls so you can get more information on the actual requests.

Going Further

In this post, I only outlined the basics of what the Laravel Debugbarincludes. It has many more features under the hood including twig integration, enabling/disabling at runtime, and bridge collectors. If you want to go further the docs cover a lot of the underlying code in more details.
This is a package I highly recommend.

reference :https://laravel-news.com/2015/02/laravel-debugbar/

2015年11月23日 星期一

AngularJS: Getting around ngApp limitations with ngModule

As you AngularJS application gets more complex you will likely come to discover that the ngApp directive has two fairly big limitations:
  1. You can only have one ng-app per page.
  2. You can only associate a single module with a single HTML element

Combine modules into a single module

One way to work around this is to “combine” multiple modules into a single module by referencing them in another module. Here is an example of what I mean:


    
        
        
    
ng-app="CombineModule">

myDiv1
ng-controller="MyControllerA"> {{name}}

myDiv2
ng-controller="MyControllerB"> {{name}}
That works, but it has it’s problems. One it’s less clear the second div myDiv2 only needs the controller from MyModuleB why combine everything. You can imagine it would become less clear as your app and therefore the number of modules grows.
Also this example works because the controllers have different names, what if they had the same names. Being able to associate different modules with different HTML elements would give us better control of our namespace.

Do it programmatically using angular.bootstrap()

You might be surprised to find out that the limitations of the ngApp are not limitations of Angular itself. Angular allows you to associate more than one module per HTML element. Angular also allows you to have multiple HTML elements on a page associate with modules. You just have to do it grammatically.
Below is an example of how to do this. In this example we have two modules each with one controller. myDiv1 is associated with both modules. WhilemyDiv2 is associated with just with a single module.


    
        
        
    
id="myDiv1">

myDiv1
ng-controller="MyControllerA"> {{name}}
ng-controller="MyControllerB"> {{name}}
id="myDiv2">

myDiv2
ng-controller="MyControllerB"> {{name}}
The output of that code is:
    myDiv1

    Bob A
    Steve B

    myDiv2

    Steve B
You can see for yourself and play around with that code at:
This gives us a lot of flexibility, the problem is it’s pretty ugly. You have to reference the element itself in your code which means you are coupling your code with the HTML. That goes against one of the main goals of Angular.

Ideal solution: A more robust ngApp (enter ngModule)

The ideal solution would be for ngApp to allow you to do everything angular.bootstrap() allows you to do. Allow you to use it on multiple HTML elements. Allow you to specify more than one module.
Normally the solution to this would be to create your own Angular directive. The problem is, how would you define that directive? You would need a module to define it in which would defeat the purpose.
To implement a directive like ngApp you would need to implement it the way ngApp is implemented. I’ll spare you the trouble, I’ve already implemented it. You can download it from this link: angular.ng-modules.js
You can also find it on GitHub at:
https://github.com/luisperezphd/ngModule
This JavaScript file introduces the ngModule directive. Here is an example of how you would rewrite the code above to use ngModule:


    
        
        
        
    
ng-modules="MyModuleA, MyModuleB">

Module A, B
ng-controller="MyControllerA"> {{name}}
ng-controller="MyControllerB"> {{name}}
ng-module="MyModuleB">

Just Module B
ng-controller="MyControllerB"> {{name}}

Notes about ngModule

You might have noticed that in one case I use the plural version of the directive ng-modules with the “s” and in another case I use the singular version without the “s” ng-module.
This was just a preference of mine. I allow for both spellings interchangeably regardless of whether you reference a single or multiple modules. I just liked how it read better.
In keeping with Angular’s convention I allow you to use any variation of the directive name. For example, the following are all valid: ng:modulex-ng-modulesdata-ng-modules, etc.
Finally you should know that while you can now associate multiple HTML elements on a single page with modules by using this directive. Those HTML elements cannot be nested. If they are nested they will not behave properly. Said another way if you associate an HTML element with a module, you can associate a child of that element with another module.

Why the ngApp limitations?

One questions that I’ve seen asked in several forums is why did the Angular team place those limitations on ngApp to begin with. After all as I mentioned above the Angular framework itself does not have those limitations. I haven’t seen an answer from the Angular team but I can speculate.
Earlier versions of angular have the “view” and “route” functionality built in. In fact, that seemed the be the expected or recommended way to use Angular. Since you only have one URL, you can’t have multiple multiple views and routes on the same page. Therefore there might have been little need to be able to associate multiple modules.
They might have felt that having a single module associated with a page made it easier to understand and use. After all you often hear Angular often being mentioned as a technology for single page applications.
They might have simply not gotten around to it since two approaches already exists for doing it. I covered them above.
They might have felt that that kind of information belongs in your code, not your markup. While all these reasons are debatable, I think this one would be the most debatable since it’s possible for a module to only contain directives for front end controls.
I mentioned above that AngularJS does not allow nesting. Meaning you can’t have a element and a child element associated with different modules. The Angular team might have felt that because of that limitation it was better to avoid the situation by only allowing one module in your HTML.

refer : http://www.simplygoodcode.com/2014/04/angularjs-getting-around-ngapp-limitations-with-ngmodule/

wibiya widget