CSC/ECE 517 Fall 2012/ch2a 2w26 aj: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 2: Line 2:


== Introduction ==
== Introduction ==
The article is intended to be an accompaniment to the SaaS video lecture 4.6  titled “Enhancing Rotten Potatoes again” <ref name="video">Enhancing Rotten Potatoes again, http://www.youtube.com/watch?v=2l9uLw3y6J8<br></ref>, part of the SaaS video lecture series for the Software Engineering for SaaS hosted on the Coursera learning network. <ref>Coursera, https://www.coursera.org/</ref><br>The Rotten Potatoes webpage, designed in the previous lectures is enhanced for implementing a new feature to add a new movie by looking up the TMDb database<ref> TMDb — The Movie Database, http://www.themoviedb.org/</ref> rather than manually entering the movie name. The flow of this article is as follows :


*The scope of discussion
*Brief description of the storyboard used for the Lo-Fi UI design discussed in previous lectures in the video lecture series,
*Explanation of Sad path, Happy Path and Bad Path
*Description of the User Story developed in the video lecture
*Elaboration of the test scenarios written for the particular User story (including scenarios for happy and sad paths) in Cucumber
*Explanation of the Background facility in Cucumber


===Code Blocks===
==Scope==
The scope of this article is limited only to the scope covered in the video lecture. The lecture builds upon Behavior-Driven Development (BDD) basics discussed in the video lectures before it and sets the reader up for upcoming lectures concerning Test-Driven Development (TDD). Hence for the purpose of this article, it is assumed that the reader has already read the material and watched the video lectures before this one in the series. Hence the setup for Cucumber, Capybara and BDD basics are excluded from this article. The resources dealing with these can be found in the SaaS lectures 4.1 to 4.5 in the series. Similarly, the theory and implementation of TDD as well as further discussion on BDD is excluded from the scope of this article. More details on these can be found in lectures 4.7 to 5.11 of the SaaS lecture series .<ref>Software Engineering for SaaS, https://class.coursera.org/saas-2012-003/class/index </ref>


==Closures in Ruby==
==A Brief Recap==
Behavior-Driven Development (BDD) is a specialized development process which concentrates more on the behavioral aspects of the application as against the actual implementation of the application. <ref>Software Engineering for SaaS, https://class.coursera.org/saas-2012-003/class/index </ref>


===What is a Closure?===
Storyboards are used to show how UI changes based on user actions. Even if it is tedious to draw sketches and storyboards, it helps build a ‘bigger picture’ understanding of the flow of the application for the non-technical stakeholders.
[[File:RottenPotatoes1.jpg|200 px|thumb|center|The Cucumber Test with Features and Scenarios(Click image to enlarge) ]]
 
===How does it work?===
 
 
===Why are closures needed?===
 
Although Closures are not mandatory requirements for a language, Closures provide an elegant way of binding the environment implicitly. Some of the popular languages like C, C++ and Java don't support Closures. Closures help in writing compact codes by avoiding the use of many arguments, as it closes the local variables in its surrounding.
 
===Other ways to use a closure===
 
Rather than calling the method <code>lambda</code>, following ways can be used to create <code>Proc</code> objects:<br><br><br>
<b>(i)</b> Using the <code>( -> )</code> syntax <br>
<code>->params  {  . . .  } </code><br>
Example: <br>
<code>
obj = ->(v1,v2) { v1 + v2 } <br>
obj.call(2,3)  # => 5
</code><br>
Note: There cannot be any space between > and opening paranthesis. <br><br>
 
<b>(ii)</b> By passing a block to the method whose last parameter is prefixed with an ampersand (&).
That parameter will receive the block as a Proc object.
<pre>def sampmeth(v1, &block)
    puts block.inspect
end
  sampmeth(1) { "a block" }
  sampmeth(3)
</pre>
produces:
<pre>
  #<Proc:0x0b5f5e@/tmp/prog1.rb:4>
  Nil
</pre><br>
<b>(iii)</b> By calling <code>Proc.new</code> by associating it with a block<br>
<pre>obj = Proc.new { "a block" }
obj  #=>  #<Proc:0x0a5e5a@/tmp/prog1.rb:1>
</pre><br>
 
===Scope of a Closure===
Closure remembers the context in which it is defined, and uses that context whenever it is called. The context may include the value of self, constants, local variables, class variables and any defined block.
   
   
<pre>
Cucumber is one of the shining tools of Rails that is used for testing purposes. It acts as a halfway between the customer and the developer by converting user stories of 3x5 cards into tests.
class ClosureExample
These tests act as Acceptance tests for ensuring the satisfaction of the customer. Also, the tests act as Integration tests that ensures the communication between modules is consistent and correct
  CONST = 1
  @@class_var = 4
 
  def return_closure
  local_var = 2
  @instance_var = 3
  lambda { [ CONST, local_var, @instance_var,  @@class_var, yield ] }
  end
 
  def update_values
    @instance_var += 1
    @@class_var += 1
  end
end


ex = ClosureExample.new
==The User Story==
block = ex.return_closure { "dummy" }
The aim of the User story described in the video is to add a new feature to the Rotten Potatoes web page, to add a new movie to the movies list on Rotten Potatoes page. But, for adding the movie to the list, it populates the data from TMDb rather than entering the information by hand. This is aimed at reducing repetitive work since the TMDb already has a good database of movies.
block.call    # => [ 1, 2, 3, 4, "dummy" ]
To do so, the ability to search TMDb from Rotten Potatoes home page needs to be incorporated in the webpage. Users can then search in TMDb if the movie is present in it and then its details can be imported into Rotten Potatoes. For integrating this feature into the application, first, a Lo-Fi UI and Storyboard is designed, which is described next.
ex.update_values
block.call    # => [ 1, 2, 4, 5, "dummy" ]


</pre>
==The StoryBoard==
The Storyboard is to be interpreted as follows
When a person wants to add a new movie to the Movies list on Rotten Potatoes, he/she will enter the new movie name and click “Search”. The controller method should search the TMDb database for the given movie. If a match is found, i.e. the movie is present in the TMDb, then the “Match” page is displayed. If there is no match, otherwise “No Match” page is displayed. These two scenarios, are the Happy Path and Sad Path implementations respectively.
[[File:Storyboard.jpg|200 px|thumb|Center|The Storyboard for the User Story. (Click Image to expand) ]]


In the above example, the return_closure method returns a lambda that accesses local variable <code>local_var</code>, instance variable <code>instance_var</code>, class variable <code>class_var</code> and constant <code>CONST</code>. Even if the block is not in the scope of the object that contains these values, it is still accessible via the closure. So, when we update these values calling the update_values method, the values accessed via the closure also get updated.
Closure is a very handy feature for Ruby developers and is used extensively. The rest of the chapter describes the implementation of Closures in different popular programming languages.
<br>
<br>
==Closures in other languages==
A closure or a closure-like implementation is available in most programming languages. Now that we have seen the implementation of closures in Ruby, let us explore the use of closures in other programming languages.<br>
===Closures in C#===
A closure in C# can be done using Lambda expressions and delegates, where a first-class function[http://en.wikipedia.org/wiki/First-class_function] references the variables in the surrounding scope. Such a referenced variable is neither a parameter of the function nor a local variable<ref>Hilyard, J. and Teilhet,S., "C# 3.0 Cookbook 3rd edition", O'reilly Pub. (2007)</ref>.
For example,
<pre>
  static void Main(string[] args)
{
var obj = ClosureFunc(1);
Console.Writeline("Output 1= " + obj(2));
Console.Writeline("Output 2= " + obj(3));
}
public static Func<int, int> ClosureFunc(inc)
{
Func<int,int> SampleFunc = delegate(int val)
{
inc = inc + 1;
return val + inc;
};
return SampleFunc;
}   
</pre>
The result obtained is:
<pre>
Output 1= 4
Output 2= 6
</pre>
Now, when we call <code>ClosureFunc</code> from <code>Main()</code>,we get a method back that increments a local variable inside the method. <code>inc</code> is a local variable of <code>ClosureFunc()</code> which is accessed inside of the delegate. So, when we call the method twice, the local variable <code>inc</code> gets incremented twice outside of its original scope.
What actually happens here is the C# compiler encapsulates the delegate and the associated local variables into a compiler generated class. So, on invoking the delegate, it creates a lambda expression to increment the value of <code>inc</code> and results in calling a method on this class.
Another way to write the ClosureFunc is using <code><b>lambda</b> ( => ) </code>
  <pre>Func<string,string> ClosureFunc = val => val + inc;</pre>
===Closures in JavaScript===
JavaScript is a dynamic and powerful scripting language which allows the use of Closures. An example of a closure in JavaScript is as follows<ref>Bhattacharya, A. , Sunder, K. , "Memory leak patterns in JavaScript", http://www.ibm.com/developerworks/web/library/wa-memleak/index.html</ref>:<pre>
  function ClosureFunc(inc)
  {
        return  SampleFunc (val) {
              return val + inc;
  }
  var obj = ClosureFunc(10);
  obj(5);  // returns 15
</pre>
Here, when a call is made to the outer function <code>ClosureFunc</code> with a parameter <code>inc</code>, the function returns with a pointer to the inner function <code>SampleFunc</code>, which is assigned to the variable <code>obj</code>.
===Closures in Perl===
Perl also supports closures extensively. Syntax for implementing closure in Perl<ref> Cozens, S., "Achieving Closure", http://www.perl.com/pub/2002/05/29/closure.html</ref> is similar to that of Ruby, which is as follows:
<pre>
    sub closurefunc {
my $inc = shift;
my $obj = sub  {
my $val = shift;
return $val + $inc;    # uses local variable inc
};
return $obj;
  }
 
  my $add3 = closurefunc(3);
  print "5 plus 3 is ":
  print $add3->(5);          #  =>  8
</pre>
Here, the <code>closurefunc</code> subroutine creates an anonymous function, which uses the local variable <code>inc</code> and returns the object <code>$obj</code>.
===Closures in Python===
Closures in python<ref>"Python Closures explained", http://www.shutupandship.com/2012/01/python-closures-explained.html</ref> are implemented as function calls. Support for closures has existed in Python since version 2.2, although the syntax of Python closures can actually confuse the user in thinking that the closures are not supported.
Consider following example code for creating an 'closurefunc' function using closures<ref>"Closures in Python : examples implementing Closures in Python", http://ynniv.com/blog/2007/08/closures-in-python.html</ref>:
<pre>
def closurefunc(x):
def inc(y):
    # x is "closed" in the definition of inc
    return y + x
return inc
inc5 = closurefunc(5)
inc10 = closurefunc(10)
inc5 (5) # returns 10
</pre>
As mentioned above, closures in Python are executed as function calls.
The call to <code><b>closurefunc</b></code> creates a binding for <code>x</code> which is referenced inside the function <code>inc</code>. In technical terms, the function <code>inc</code> is closed over the variable <code><b>x</b></code>.
If we go ahead and delete the <code><b>closurefunc</b></code> function from the global namespace,
<pre>
del closurefunc
</pre>
even then,
<pre>
>>inc10(5) # returns 15
</pre>
Why does this happen? Each call to <code><b>closurefunc</b></code> creates a new instance, returning an <code>inc</code> function object and assigning it to the <code>inc5</code> and <code>inc10</code>. Each instance has a link to a different binding of <code>x</code>. Hence, the function <code>inc</code> will have access to <code>x</code> even if the scope where <code>x</code> was defined doesn’t exist anymore.
The above example shows the closure of <code>x</code> being used to eliminate either a global or a constant, depending on the nature of <code>x</code>.
Python also supports the use of closures through the <code><b>lambda</b></code> constructs.
The difference between a normal function and a <code><b>lambda</b></code> function is shown below
<pre>
>>> def f (x): return x**2  #normal function definition
...
>>> print f(8)
64
>>> g = lambda x: x**2      #demo of lambda construct
>>>
>>> print g(8)
64
</pre>
As you can see, the <code><b>lambda</b></code> function is defined on the fly and always returns an expression. If we write a new <code><b>closurefunc</b></code> function using the <code><b>lambda</b></code> construct, we will see the following
<pre>
>>def closurefunc(n): return lambda x: x + n #creation of lambda function
>>f = closurefunc(2)
>>g = closurefunc(6)
>>print f(42), g(42)
>>44, 48
</pre>
The lambda function is created on the fly and returns an expression which is assigned to <code>f</code> and <code>g</code>. The <code><b>lambda</b></code> construct works even without assigning the returned expression, as shown next
<pre>
>>print closurefunc(22)(33)
>>55
</pre>
<br>
==Conclusion==
In conclusion, a brief introduction to closures and its usage in dynamic scripting languages has been provided above. The code examples illustrate the syntax and semantics supported by these languages. A concise comparison between the implementation in these languages is summarized below. References are provided for the users to enhance their understanding of the subject. <br>
{| class="wikitable"
|-
!  !! Ruby !! C# !! JavaScript !! Perl !! Python !! C / C++ / Java
|-
| <b>Support for Closures</b>|| Yes|| Yes|| Yes|| Yes|| Yes|| No
|-
| <b>Closure implementation using</b>|| Proc, block and Lambdas || Delegates and First Class functions || Unnamed functions || Anonymous functions || Named function calls, Lambda|| No
|-
| <b>Support for Lambda implementation</b>|| Yes|| Yes|| No|| No direct support, can be simulated using anonymous functions|| Yes|| No
|}
<br>
== Topical References ==


<references/>
<references/>
<br>
== Further Reading ==
== Further Reading ==



Revision as of 01:20, 27 October 2012

SaaS 4.6 Enhancing Rotten Potatoes again

Introduction

The article is intended to be an accompaniment to the SaaS video lecture 4.6  titled “Enhancing Rotten Potatoes again” <ref name="video">Enhancing Rotten Potatoes again, http://www.youtube.com/watch?v=2l9uLw3y6J8
</ref>, part of the SaaS video lecture series for the Software Engineering for SaaS hosted on the Coursera learning network. <ref>Coursera, https://www.coursera.org/</ref>
The Rotten Potatoes webpage, designed in the previous lectures is enhanced for implementing a new feature to add a new movie by looking up the TMDb database<ref> TMDb — The Movie Database, http://www.themoviedb.org/</ref> rather than manually entering the movie name. The flow of this article is as follows :

  • The scope of discussion
  • Brief description of the storyboard used for the Lo-Fi UI design discussed in previous lectures in the video lecture series,
  • Explanation of Sad path, Happy Path and Bad Path
  • Description of the User Story developed in the video lecture
  • Elaboration of the test scenarios written for the particular User story (including scenarios for happy and sad paths) in Cucumber
  • Explanation of the Background facility in Cucumber

Scope

The scope of this article is limited only to the scope covered in the video lecture. The lecture builds upon Behavior-Driven Development (BDD) basics discussed in the video lectures before it and sets the reader up for upcoming lectures concerning Test-Driven Development (TDD). Hence for the purpose of this article, it is assumed that the reader has already read the material and watched the video lectures before this one in the series. Hence the setup for Cucumber, Capybara and BDD basics are excluded from this article. The resources dealing with these can be found in the SaaS lectures 4.1 to 4.5 in the series. Similarly, the theory and implementation of TDD as well as further discussion on BDD is excluded from the scope of this article. More details on these can be found in lectures 4.7 to 5.11 of the SaaS lecture series .<ref>Software Engineering for SaaS, https://class.coursera.org/saas-2012-003/class/index </ref>

A Brief Recap

Behavior-Driven Development (BDD) is a specialized development process which concentrates more on the behavioral aspects of the application as against the actual implementation of the application. <ref>Software Engineering for SaaS, https://class.coursera.org/saas-2012-003/class/index </ref>

Storyboards are used to show how UI changes based on user actions. Even if it is tedious to draw sketches and storyboards, it helps build a ‘bigger picture’ understanding of the flow of the application for the non-technical stakeholders.

Cucumber is one of the shining tools of Rails that is used for testing purposes. It acts as a halfway between the customer and the developer by converting user stories of 3x5 cards into tests. These tests act as Acceptance tests for ensuring the satisfaction of the customer. Also, the tests act as Integration tests that ensures the communication between modules is consistent and correct

The User Story

The aim of the User story described in the video is to add a new feature to the Rotten Potatoes web page, to add a new movie to the movies list on Rotten Potatoes page. But, for adding the movie to the list, it populates the data from TMDb rather than entering the information by hand. This is aimed at reducing repetitive work since the TMDb already has a good database of movies. To do so, the ability to search TMDb from Rotten Potatoes home page needs to be incorporated in the webpage. Users can then search in TMDb if the movie is present in it and then its details can be imported into Rotten Potatoes. For integrating this feature into the application, first, a Lo-Fi UI and Storyboard is designed, which is described next.

The StoryBoard

The Storyboard is to be interpreted as follows When a person wants to add a new movie to the Movies list on Rotten Potatoes, he/she will enter the new movie name and click “Search”. The controller method should search the TMDb database for the given movie. If a match is found, i.e. the movie is present in the TMDb, then the “Match” page is displayed. If there is no match, otherwise “No Match” page is displayed. These two scenarios, are the Happy Path and Sad Path implementations respectively.

The Storyboard for the User Story. (Click Image to expand)


<references/>

Further Reading

Wikipedia - Closures : everything there is to know about Closures on one page.

Reg Braithwaite - Closures and Higher-Order Functions : gives Ruby examples of specialized Closures.

Closures in Ruby : gives a detailed explanation of Closures in Ruby.

MSDN Magazine - Functional Programming .NET Development : examples of functional style with Closures in C#.

Eric Kidd - Some useful closures, in Ruby : demonstrates more examples of curried and specialized Closures in Ruby.

Jim Weirich - Top Ten Reasons I Like Ruby - Blocks and Closures : provides several examples of how Closures can be useful in Ruby.

C# in Depth - The Beauty of Closures : demonstrates Closures in C#.

Martin Fowler - Closure : provides a basic definition of Closures and gives a few very basic examples.

Javascript Closures : demonstrates Javascript Closures in callbacks.

Alan Skorkin - Closures - A Simple Explanation : gives a high-level overview of Closures using Ruby examples.

IBM Developerworks - Crossing borders : Closures : gives Ruby examples where Closures are useful.

Sam Danielson - An Introduction to Closures in Ruby : high-level overview of using Closures in Ruby.