This theme does everything you could possibly want it to do and not only that, it is beautifully designed and extremely intuitive to use.
This theme does everything you could possibly want it to do and not only that, it is beautifully designed and extremely intuitive to use.
This theme does everything you could possibly want it to do and not only that, it is beautifully designed and extremely intuitive to use.
This theme does everything you could possibly want it to do and not only that, it is beautifully designed and extremely intuitive to use.
This theme does everything you could possibly want it to do and not only that, it is beautifully designed and extremely intuitive to use.
This theme does everything you could possibly want it to do and not only that, it is beautifully designed and extremely intuitive to use.


🌥Weather Channel
Search a City:
Search
Current Date
Temp:
Wind:
Humidity:
UV Index:
Five Day Forecast:


This information appears on the installation profile, organization pages, search results, and beyond.
Will make this eligible for harvesting etc.
Important Restoring a previously deleted entity will likely trigger significant processing
Important This will trigger a metadata synchronization with the installation, which may update the registry


2021 Coding & Cocktails Angular Series
Angular Pt. 1: SPA Day
slides
worksheet
Angular Pt. 2: Playing with Blocks
slides
worksheet
Angular Pt. 3: Fake It ’Til You Make It
slides
worksheet
Angular Pt. 4: Go Fetch
slides
worksheet


Mathematics beauty lies in the creation of very complex patterns using only simple steps. This visualization is a good example. Here is the simpe process used to create these advanced representations.
Draw a circle, and add some graduations on it in order to split the circle into arcs of same length. Let's consider we spitted the circle into 5 equal arcs.
If we want to display the table of 2 representation, we just have to draw some segments between our graduation, each one linking the multiplied value to the final result. For instance:
We do not have a enough graduation for the third one, as we need a sixth graduation. So, just apply a modulo of your total number of graduation to get an existing one. In this case, link graduation 3 to 6 % 5 = 1 graduation.
Repeat this step until you loop on already existing values.
This video has been greatly inspired by a YouTube video from Mickaël Launay, a French YouTuber:
Source code is available on GitHub: https://github.com/jpetitcolas/multiplication-circle.
This project has been released under MIT license, meaning you can do whatever you want with it, without any restrictions.


A Selenium course that takes you step-by-step through building a custom Selenium Framework from scratch.
First Element
First Element
Second Element
Third Element
Fourth Element
First Element Text
First Element
First Element
First Element
First Element
Second Element
First Element
First Element
First Element
Second Element
Third Element
First Element
First Element
Second Element
Third Element
First Element
Second Element
First Element Foo Found
First Element Text - Dynamic Text
First Element w/ Space
First Element
First Element w/ Case
First Element w/ Space & Case
First Element
Second Element
First substring-before Element : Dynamic substring-before Text
First substring-after Element : Dynamic substring-after Text


The visual arts are art forms such as painting, drawing, printmaking, sculpture, ceramics, photography, video, filmmaking, design, crafts and architecture. Many artistic disciplines such as performing arts, conceptual art, and textile arts also involve aspects of visual arts as well as arts of other types. Also included within the visual arts[1] are the applied arts[2] such as industrial design, graphic design, fashion design, interior design and decorative art.[3] Current usage of the term "visual arts" includes fine art as well as the applied or decorative arts and crafts, but this was not always the case. Before the Arts and Crafts Movement in Britain and elsewhere at the turn of the 20th century, the term 'artist' had for some centuries often been restricted to a person working in the fine arts (such as painting, sculpture, or printmaking) and not the decorative arts, craft, or applied Visual arts media. The distinction was emphasized by artists of the Arts and Crafts Movement, who valued vernacular art forms as much as high forms.[4] Art schools made a distinction between the fine arts and the crafts, maintaining that a craftsperson could not be considered a practitioner of the arts. The Metropolitan Museum of Art in Manhattan. Museums constitute a primary forum for the display of visual arts. The increasing tendency to privilege painting, and to a lesser degree sculpture, above other arts has been a feature of Western art as well as East Asian art. In both regions painting has been seen as relying to the highest degree on the imagination of the artist, and the furthest removed from manual labour – in Chinese painting the most highly valued styles were those of "scholar-painting", at least in theory practiced by gentleman amateurs. The Western hierarchy of genres reflected similar attitudes.
CEO & Founder
Some text that describes me lorem ipsum ipsum lorem.
<EMAIL_ADDRESS>Art Director
Some text that describes me lorem ipsum ipsum lorem.
<EMAIL_ADDRESS>Designer
Some text that describes me lorem ipsum ipsum lorem.
john@example.com


Intro:
Around 7 weeks ago I’ve had to quit my favorite pastime, the happy little green plant, so my grades could get better in school. Since then I’ve gotten very interested in the “alternative” approach and have been trying many different things available through the internet, such as this.
Preparation:
1 oz of dried Sinicuichi leaves were vigorously boiled with four cups of water until most plant matter sank to the bottom. The leaves were then strained from the brown liquid, and another extraction done, this time yielding a lighter, “dirty orange” colored liquid. The extracts were combined in a medium sized pot and were brought to boiling. This produced incredible amounts of orange foam in just a few seconds, after which I pointed my hairdryer (set on cool) on the liquid. The foam instantly disappeared, and I was able to put the stove to full power while the hairdryer kept the liquid at a low boil that produced little foam. The 8 cups reduced incredibly fast (25 min) after which I turned down the heat and was left with about ˝ cup of orange-brown sludge. This was dried with said hairdryer in a Pyrex dish, leaving me 2 teaspoons of dark brown residue.
Settings:
Most of the reports I’d read about Sinicuichi were pretty variable as to the effects, but in no case did it say that the experience was particularly overpowering like DMT and Salvia can be. I therefore decided that my friend and me didn’t need a sitter and that we could both enjoy the substance together. We each ate one half of the powder around 10pm at my house (parents are in Europe). The powder was very bitter, at least the part that dissolved on our tongue, but the aftertaste was washed away easily with a little OJ. The next half hour was spent satisfying my addiction to Mancala, it’s that millennia old game from Africa.
Effects:
There were no effects for the first half hour, besides a slight stomach-ache. After half an hour my friend (from now on T) said he felt a little dissociated. We quit playing Mancala and started watching The Return of the King he had just downloaded on the new TV. For me definite non-placebo effects started after 45 minutes. I would feel normal for 2-3 minutes at a time, after which a wave of stomach-cranking nausea would hit me, and my mind would kind of blend the meaning of objects and their actual appearance.
For example the remote would still look like a remote, but I was thinking about it as the table it was on. This was not pleasurable because of the intense nausea that came with it, which would ebb to almost normal after a minute or so. T said he felt fuzzy and dissociated, very similar as to when you are sick, but without the fever. There were no visual or auditory effects at all. For me it simply felt as if my entire brain and body were being polluted with some poison, which would come and go every few minutes. We quit watching the movie at the place where the wounded Faramir is brought up the streets to the king, around 100 minutes after ingestion. The effects had now reached a plateau, and we both felt very tired and sick so we decided to sleep it off. I fell asleep during the first “good” period I hit, and still remember that I was worried the room might get to cold ‘cause the window was opened.
The rest of the night is a blur. I remember waking up at around 4 or so because I was freezing uncontrollably. My blanket was on the floor, and I barely managed to pick it up and close the window, never reaching full consciousness. The next 5 hours were spent in a sort of sleep / wake world. I remember having nightmares about being in a prison which allowed me to see my surroundings but not understand them, a kind of mental block between sleeping and waking. Very uncomfortable. At other times my thoughts would just be too random and poisoned to make much sense. T finally woke me at 9, and he had had a horrible night as well. T also had a giant headache and felt very sick, and he froze during the night as well. I did not have such a bad headache, but instead felt totally weak.
Every one of my muscles felt as if I’d just had the most intense workout. I was shaking from exhaustion and could hardly walk because my muscles were aching so bad. Pouring milk or water was impossible. In addition, my insides hurt and were very touch sensitive. Even breathing was hard, I tried to cough once but was too weak to do it.
Our wretchedness slowly decreased during the day, which we spent laying down. The next day was almost normal, and today I can finally say I’m back to baseline. Btw I did not get sick with infection even though my throat, just as everything else, was swollen considerably the first day and I froze all night long. T says he still has a slight headache.
Conclusion:
I don’t know what to think. This body reaction was the weirdest I’ve ever had, I just felt so sick and tired all over and my muscles were totally powered out. My joints ached, the skin was sensitive and internal organs hurt. I should note that my body smelt totally like Sinicuichi on the second day, even though I showered thrice. Maybe it gets excreted through the skin. I have a new a new-found respect for all herbal remedies and will avoid the best I can.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


The watson-speech library allows you to easily add voice recognition and synthesis to any web app with minimal code.
Complete source code for these examples is available on GitHub.
(user-provided or downloaded - several sample files available in static/ folder)
{speaker_labels: true}
, output to console
{resultsBySpeaker: true}
, output to console
{resultsBySpeaker: true}
, output HTML
realtime
and TimingStream
options


Introduction
Command-line parameters are passed to a program at runt-time by the operating system when the program is requested by another program, such as a command interpreter ("shell") like
cmd.exe on Windows or
bash on Linux and OS X. The user types a command and the shell calls the operating system to run the program. Exactly how this is done is beyond the scope of this article (on Windows, look up
CreateProcess; on UNIX and UNIX-like systems look up
fork(3) and
exec(3) in the manual).
The uses for command-line parameters are various, but the main two are:
- Modifying program behaviour - command-line parameters can be used to tell a program how you expect it to behave; for example, some programs have a -q (quiet) option to tell them not to output as much text.
- Having a program run without user interaction - this is especially useful for programs that are called from scripts or other programs.
The command-line
Adding the ability to parse command-line parameters to a program is very easy. Every C and C++ program has a
main function. In a program without the capability to parse its command-line,
main is usually defined like this:
To see the command-line we must add two parameters to main which are, by convention, named
argc (
argument
count) and
argv (
argument
vector [here, vector refers to an array, not a C++ or Euclidean vector]).
argc has the type
int and
argv usually has the type
char** or
char* [] (see below).
main now looks like this:
|
int main(int argc, char* argv[]) // or char** argv
| |
argc tells you how many command-line arguments there were. It is always at least 1, because the first string in
argv (
argv[0]) is the command used to invoke the program.
argv contains the actual command-line arguments as an array of strings, the first of which (as we have already discovered) is the program's name. Try this example:
1 2 3 4 5 6 7
|
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << argv[0] << std::endl;
return 0;
}
| |
This program will print the name of the command you used to run it: if you called the executable "a.exe" (Windows) or "a.out" (UNIX) it would likely print "a.exe" or "./a.out" (if you ran it from the shell) respectively.
Earlier it was mentioned that
argc contains the number of arguments passed to the program. This is useful as it can tell us when the user hasn't passed the correct number of arguments, and we can then inform the user of how to run our program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
#include <iostream>
int main(int argc, char* argv[])
{
// Check the number of parameters
if (argc < 2) {
// Tell the user how to run the program
std::cerr << "Usage: " << argv[0] << " NAME" << std::endl;
/* "Usage messages" are a conventional way of telling the user
* how to run a program if they enter the command incorrectly.
*/
return 1;
}
// Print the user's name:
std::cout << argv[0] << "says hello, " << argv[1] << "!" << std::endl;
return 0;
}
| |
Example output (no arguments passed):
Usage: a.exe <NAME>
Example output (one argument passed):
a.exe says hello, Chris!
Arguments and Parameters
Arguments and parameters are strings passed to your program to give it information. A program for moving files, for example, may be invoked with two arguments - the source file and the destination:
move /path/to/source /path/to/destination (note: on Windows these paths would use backslashes instead [and would probably have a drive prefix, like
C:], however as Windows supports backwards and forwards slashes in paths while UNIX systems only support forward slashes, forward slashes will be used throughout this article).
In this example, the program would look something like this:
1 2 3 4 5 6 7 8 9 10 11
|
#include <iostream>
int main(int argc, char* argv[])
{
if (argc < 3) { // We expect 3 arguments: the program name, the source path and the destination path
std::cerr << "Usage: " << argv[0] << "SOURCE DESTINATION" << std::endl;
return 1;
}
return move(argv[1], argv[2]); // Implementation of the move function is platform dependent
// and beyond the scope of this article, so it is left out.
}
| |
If we wanted to allow the use of multiple source paths we could use a loop and a std::vector:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#include <iostream>
#include <string>
#include <vector>
int main(int argc, char* argv[])
{
if (argc < 3) { // We expect 3 arguments: the program name, the source path and the destination path
std::cerr << "Usage: " << argv[0] << "SOURCE DESTINATION" << std::endl;
return 1;
}
std::vector <std::string> sources;
std::string destination;
for (int i = 1; i < argc; ++i) { // Remember argv[0] is the path to the program, we want from argv[1] onwards
if (i + 1 < argc)
sources.push_back(argv[i]); // Add all but the last argument to the vector.
else
destination = argv[i];
}
return move(sources, destination);
| |
Arguments may be passed as values to options. An option usually starts with a single hyphen (-) for a "short option" or a double hyphen (--) for a "long option" on UNIX, or a forward slash on Windows. Hyphens (single and double) will be used in this article. Continuing the example of the
move program, the program could use a
-d/
--destination option to tell it which path is the source and which is the destination, as in
move -d /path/to/destination /path/to/source and
move --destination /path/to/destination /path/to/source. Options are always right-associative, meaning that the argument to an option is always the text directly to the right of it.
Let's extend the previous example to use the destination option.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
#include <iostream>
#include <string>
#include <vector>
int main(int argc, char* argv[])
{
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << "--destination DESTINATION SOURCE" << std::endl;
return 1;
}
std::vector <std::string> sources;
std::string destination;
for (int i = 1; i < argc; ++i) {
if (std::string(argv[i]) == "--destination") {
if (i + 1 < argc) { // Make sure we aren't at the end of argv!
destination = argv[i++]; // Increment 'i' so we don't get the argument as the next argv[i].
} else { // Uh-oh, there was no argument to the destination option.
std::cerr << "--destination option requires one argument." << std::endl;
return 1;
}
} else {
sources.push_back(argv[i]);
}
}
return move(sources, destination);
}
| |
Now the parameters can be in any order as long as the destination path is immediately to the right of "--destination".
More on usage messages
Our usage message is helpful, but if we need to print it from more than one place, we have to copy the code. Obviously the way around this is to use a function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
#include <iostream>
#include <string>
#include <vector>
static void show_usage(std::string name)
{
std::cerr << "Usage: " << argv[0] << " <option(s)> SOURCES"
<< "Options:\n"
<< "\t-h,--help\t\tShow this help message\n"
<< "\t-d,--destination DESTINATION\tSpecify the destination path"
<< std::endl;
}
int main(int argc, char* argv[])
{
if (argc < 3) {
show_usage(argv[0]);
return 1;
}
std::vector <std::string> sources;
std::string destination;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if ((arg == "-h") || (arg == "--help")) {
show_usage(argv[0]);
return 0;
} else if ((arg == "-d") || (arg == "--destination")) {
if (i + 1 < argc) { // Make sure we aren't at the end of argv!
destination = argv[i++]; // Increment 'i' so we don't get the argument as the next argv[i].
} else { // Uh-oh, there was no argument to the destination option.
std::cerr << "--destination option requires one argument." << std::endl;
return 1;
}
} else {
sources.push_back(argv[i]);
}
}
return move(sources, destination);
}
| |
Now, rather than having to guess, the user can call our program with the
-h or
--help options to find out how to run the command.
Getopt
These methods of finding command-line arguments are simple and not very robust. The best way of finding options is using the
getopt family of functions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
#include <unistd.h>
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#include <getopt.h>
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
| |
(from the
manual page)
The
manual page has examples of how to use them.


Work-Study Program
What is Work-Study?
Work-Study is a program that is funded by the government. It offers financial support to students with a demonstrated financial need. Eligible students may use their award by obtaining a Work-Study job at the University or with an approved off-campus employer. Work-Study funds must be used from September 19, 2016, to June 16, 2017.
Eligibility
To be eligible, you must:
- File your FAFSA by the March 2 deadline. (Note: FAFSA is available each year beginning October 1.)
- Demonstrate a financial need, as determined by the Financial Aid Office.
- Accept your award via R’Web.
- Remain enrolled, and maintain “Satisfactory Academic Progress” while working under the program (i.e. a minimum cumulative GPA of 2.0).
- Have used your Work-Study allocation the previous award year (for continuing students only). If you did not use previous funds, you may not be eligible for future funds.
If you qualify for Work-Study, you will be notified in your financial aid award letter. The gross earnings you can receive under the program will also be included in the letter.
Deadlines for 2016-2017
Work-Study funds can only be used between September 19, 2016, and June 16, 2017.
Work-Study Orientations
New Work-Study students are encouraged to attend one of the following orientations PRIOR to applying for Work-Study positions.
- Monday, Nov. 7, 2016, at 1-2 pm in HUB 268
- Wednesday, Jan. 25, 2017, at 11 am-12:30 pm in HUB 268
- Thursday, Feb. 23, 2017, at 11 am-12:30 pm in HUB 260
If you can't attend a Work-Study orientation, visit the Virtual Career Center. Click on the Work-Study tab to view an online orientation presentation. Otherwise, get the need-to-know highlights by contacting the Work-Study Coordinator at<PHONE_NUMBER>.
Work-Study Benefits
Use your Work-Study award and enjoy the following:
- Access to more on-campus jobs
- A flexible schedule for academics
- Saved gas money and travel time
- Paid experience
- Transferable skills to build your resume
- An established network
- The potential to gain academic credit for an internship
- A meaningful place within the UCR community
Questions?
Contact the Career Center
at<PHONE_NUMBER>
or<EMAIL_ADDRESS>for help with:
- Job search assistance
- Help with Work-Study job application
- Drop-In counseling
Contact Financial Aid
at<PHONE_NUMBER>
or<EMAIL_ADDRESS>for help with
- Work-Study eligibility
- Award adjustments
- Letter of Clearance appointments
- Paycheck pick up


rotten > Library > Travel > Disneyland
Disneyland
Few places of entertainment on Earth have garnered as much wonder, legend, or controversy as Disneyland, the Walt Disney Company amusement park, which was the first large-scale implementation of Disney approach to fantasy, story, and crowd control.
Places of Family Amusement are not new in the world, and there has certainly grown a science to them not unlike that of keeping a travelling circus intact, or maintaining national parks. But more than those who came before them, Disney and his creative team focused on the presentation of Disneyland, ensuring that it would be as controlled and predictable a fiction as their movies, records and television shows had been up to that point.
Walking into Disneyland is like a entering the sweeping shot of a fantasy movie, with an town square reaching forward to a breathtaking castle. Every aspect of the park was said to be planned ahead with the energy of one of the Disney animated features, with artists from various productions brought in to work on the look and style of the place. Actors from many Disney features appear as the voices of birds, announcers and narrators in the park.
But all this wonder hides how extensive the Disney planning really is.
When you enter Disneyland, you are actually on the top floor of a giant complex of underground facilities, providing most of the "heart and health" of the park with security, employee facilities, garbage collection and other important administrative aspects all hidden from view. You don't see garbage stacked outside Disneyland waiting to be picked up, and you never see an employee shuffling out to the lot after a long day. The park has even developed its own nomenclature to insulate gritty details from the public; a protein spill is the code that a child's vomit needs to be mopped up.
It is said that Walt Disney planned the park to the point of the placement of wastebaskets: He supposedly took a snack that might be purchased at a stand, walked until he finished it, and decreed that no trashcan would be further than that distance from any other. There are few places outside of Las Vegas where such grandiose and breathtakingly anal plans would be taken seriously, both in implementation and in believing that such forethought existed. And Las Vegas was nowhere near Disneyland's level for years.
This has caused such urban legends as the "Disney Tapes", where Walt Disney was said to have left film loops to be played after his death for several years, his forward-thinking genius so amazing he could predict what would be awaiting the company in the ensuing years; this is actually a core part of Isaac Asimov's Foundation series of novels, and not the real case. It is thought that promotional films that Disney made before his death regarding EPCOT and other projects were the source of this rumor.
Some Flaws in the Facade
It should also be remembered that Disneyland was an amazing mess on its opening day in July 17, 1955. Many attractions weren't built yet, the Main Street asphalt was still soft, and technical difficulties were everywhere. But over time, the bugs were worked out, except for the occasional death on the property.
There have been several deaths at Disneyland, more than the company would prefer to admit. The possibility of getting maimed or killed in the park is just something they would rather you didn't concern yourself with.
On Christmas Eve in 1998, Microsoft employee Luan Phi Dawson was killed by a flying metal cleat, ripped from the sailing ship Columbia by a mooring cable. The rope should not have been secured, because the vessel was coming in to the dock too fast to stop. But the rope was supposed to break when it was stretched too tight, in order to prevent a piece of the ship from getting torn off and hurting somebody. (Evidently nobody ever tested this theory.) Lawyers for the park settled with the Dawson family in October 2000 for an undisclosed sum.
Other results of Disneyland have been a wholescale change in how Amusement Parks have had to compete over the years, with larger and larger parks being built across the country to compete with them. Busch Gardens, Six Flags, and other gigantic parks have overrun the tiny tourist attractions of old, and while it may not be a major tragedy to miss out on paying $5 to see an old mummy, playing upwards of $30 to wait around in lines to get on yawning metal thrill rides is no great experience either.
There is worthwhile discussion of the effect that Disneyland has had on the surrounding town of Anaheim.
Even Disneyland itself was dwarfed by Walt Disney World in Orlando, Florida, whose ambitious plans, massive scale, and frightening governmental aspects are worthy of an entry in itself.
Timeline
| 1954 |
McDonald's franchise agent Ray Kroc unsuccessfully appeals to Walt Disney about opening a restaurant in Disneyland:
Dear Walt,
I feel somewhat presumptuous addressing you in this way. Yet I am sure you would not want me to address you any other way... My name is Ray A. Kroc... I look over the Company A picture we had taken in Sound Beach, Conn. many times and recall a lot of pleasant memories.
I have very recently taken over the national franchise of the McDonald's system. I would like to inquiry if there may be an opportunity for a McDonald's in your Disneyland Development.
|
| 17 Jul 1955 |
Disneyland opens in Anaheim, California. In the words of Walt Disney,
"That place is my baby, and I would prostitute myself for it." |
| May 1964 |
Mark Maples is killed on the Matterhorn. |
| Jun 1966 |
Thomas Guy Cleveland is killed by the Monorail. |
| Aug 1967 |
Ricky Lee Yama is killed by the PeopleMover. |
| 6 Aug 1970 |
750 unkempt Yippies show up at Disneyland, hell-bent "to liberate Minnie Mouse, have free rein of the park and infiltrate Tom Sawyer's Island," according to Youth International Party leaflets. Instead, they wind up scuffling with Disney security and other patrons, eventually prompting Anaheim police to close the park early and forcibly eject the dirty longhairs. |
| Jun 1973 |
Bogden Delaurot drowns in the Rivers of America. |
| 8 Jul 1974 |
Park employee Deborah Stone is crushed to death at America Sings. |
| 7 Jun 1980 |
Gerardo Gonzales crushed to death on the PeopleMover. |
| 7 Mar 1981 |
Eighteen year old Mel Yorba is stabbed to death at Disneyland, near the Matterhorn ride. He made the fatal mistake of grabbing at James O'Driscoll's girlfriend. O'Driscoll apparently retaliated with a sharp and pointy knife, and was found ninety minutes later hiding in Tomorrowland shrubbery. A jury trial ended in deadlock over his second degree murder charge. |
| 4 Jun 1983 |
Philip Straughan drowns in the Rivers of America. |
| 3 Jan 1984 |
Dolly Regene Young is killed on the Matterhorn. |
| 24 Dec 1988 |
Microsoft employee Luan Phi Dawson is struck in the head by a flying metal cleat, ripped from the sailing ship Columbia by a mooring cable.   The Boozers file suit for emotional distress. Disney settles the case in 1990 for an undisclosed sum. |
| 7 Nov 1989 |
After being sentenced to death, convicted serial killer Richard Ramirez tells reporters: "Big deal. Death always went with the territory. I'll see you at Disneyland." |
| 31 Mar 1990 |
A support arm collapses on the Dumbo ride, injuring a 13-year-old Canadian girl. |
| Jul 1995 |
Zipora Jacob suffers what she alleges to be a brain hemorrhage stepping off the Indiana Jones Adventure. Disney settles her case in 1999 for an undisclosed sum. |
| 17 Aug 1995 |
Armed robbers mug former Mouseketeer Billie Jean Matay in a Disneyland parking lot. Afterwards, while she is reporting the incident to security, Matay's three young grandchildren witness several costumed performers backstage with their heads removed. Matay sues the park for emotional distress, but the case is thrown out of court. |
| Jan 1998 |
Big Thunder Mountain Railroad inclicts a serious injury to 5-year-old David Fackler's left foot, necessitating toe amputations. |
| 28 Nov 1998 |
Deborah Bynum suffers what she alleges to be a brain hemorrhage on the Indiana Jones Adventure. Disney settles her case in 2001 for an undisclosed sum. |
| 18 Dec 1998 |
McDonald's opens a french fry stand inside Disneyland, housed inside a covered wagon in Frontierland. |
| 31 Jul 2000 |
A wheel-support arm breaks on Space Mountain, inflicting a sprained foot on one guest and bruises on eight others, as their car derails and skids to abrupt halt. |
| 22 Sep 2000 |
4-year-old Brandon Zucker suffers severe brain damage when he gets trapped underneath the ride vehicle in Roger Rabbit's Car Toon Spin. |
| 21 Dec 2000 |
The Alice in Wonderland ride crushes the foot and leg of a 15-year-old Arizona boy. |
| 21 Jan 2001 |
A 6-year-old girl loses most of her left index finger playing with a toy rifle on Tom Sawyer Island. |
| 1 Feb 2001 |
Melanie Hershock and her toddler are knocked backward while trying to get off the Pirates of the Caribbean ride, due to operator error. Hershock suffers injuries to her head and neck. |
| 4 May 2001 |
27 guests and two cast members are injured when a 20-foot oak tree topples over and smashes into a popcorn stand in Frontierland. 73-year-old Jeanne Gill suffers a fractured pelvis. |
| Dec 2001 |
A 15-year-old breaks his leg on Alice in Wonderland when his foot is caught between the ride vehicle and guard rail. |
| 22 Apr 2003 |
Disneyland cast member Christopher Bowman falls 42 feet to his death in the Hyperion Theatre while changing lightbulbs for "Disney's Aladdin: A Musical Spectacular." |
| 5 Sep 2003 |
One guest is killed and 10 others injured when the Big Thunder Mountain Railroad coaster jumps the tracks in Frontierland. |
| 16 Oct 2003 |
Cal OSHA fines Disneyland $18,530 for safe workplace violations which contributed to the death of Christopher Bowman. |
| 30 Nov 2003 |
Walt Disney's nephew Roy E. Disney angrily resigns from the Walt Disney Company board of directors. Among his issues with Michael Eisner: "The timidity of your investments in our theme park business. At Disney's California Adventure, Paris, and now in Hong Kong, you have tried to build parks 'on the cheap' and they show it and the attendance figures reflect it." |
| 8 Jul 2004 |
A Canadian family is taken to the hospital after two trains collide in brake zone 4 of Big Thunder Mountain Railroad in Frontierland. A Cal-OSHA report later determines that cast member James Nerrie had precipitated the accident by improperly removing a train from service. |
Pornopolis |
Rotten |
Faces of Death |
Famous Nudes
|


(Deprecated API)
(Deprecated API)
(Deprecated API)
Includes enterprise licensing and support
The Google Local Search API is a JavaScript library that allows you to embed Google Local Search in your web pages and other web applications. For Flash, and other non-JavaScript environments, the API exposes a raw interface that returns JSON-encoded results that are easily processed by most languages and runtimes. Read more in the JSON Developer's Guide.
This developer's guide provides a basic model for using the Google Local Search API, along with granular explanations of the API's configurable JavaScript components. You can use this guide to configure Local Search on your page.
This documentation is intended for developers who wish to add Google Local Search functionality to their pages using the Local Search API.
The following example creates an instance of Local Search on your page. This Local Search instance is controlled by a text input field and clear button to clear search results after a search.
Warning: You need your own API key in order to use the Local Search API. In the example below, replace "INSERT-YOUR-KEY" with your own, unique key. Without a unique key, these examples won't work.
<DOCTYPE html>   <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Google Search API Sample</title>

Loading...

To begin using the Google APIs, first you need to sign up for an API key. The API key costs nothing, and allows us to contact you directly if we detect an issue with your site.
To begin using the Local Search API, include the following script in the header of your web page. Enter your Google API key where it says INSERT-YOUR-KEY
in the snippet below.
Warning: You need your own API key in order to use this API. In the example below, replace "INSERT-YOUR-KEY
" with your own, unique key. Without your own key, these examples won't work.

Next, load the Google search module with google.load(module, version)
, where:
module
calls the specific API module you wish to use on your page (in this case, search
).
version
is the version number of the module you wish to load (in this case, 1
).

You can find out more about google.load in the Google Loader developer's guide.
The google.search.LocalSearch
constructor initializes the Local Search service so you can execute Local Search queries and display results. The methods and properties described below apply to all objects that inherit from this base class. Each of those objects may supply additional interfaces as well.
.execute(query)
initiates a new search, where query
supplies the search term(s).
This method populates the object with the corresponding set of results, and calls the registered .setSearchCompleteCallback()
handler.
.execute()
has no return value.
.setSearchCompleteCallback(object, method, opt_arguments?)
registers an object and method to notify when a search completes, where:
object
supplies an application-level object that defines the context in which to call the specified method.
method
supplies the search completion handler function, which checks for results and appends them to HTML nodes.
opt_arguments
allows you to optionally pass in a list of arguments, in order, to the specified method. If you choose to use opt_arguments
, you must pass in a list (null
is also acceptable).
localSearch.setSearchCompleteCallback(handler, handler.method, [[1, 2, 3]);
, then you execute handler.method(1, 2, 3);
when the search completes.
In this API, the calls are asynchronous. Therefore, you can't block on the return and then use the results. Rather, you have to use a callback, which will execute a method upon the return of the results.
.setSearchCompleteCallback()
has no return value.
.setOnLoadCallback(callback)
is a static function that registers the specified handler function to be called once the page containing this call loads, where callback
is a required function called when the containing document is loaded and the API is ready for use (e.g., after onLoad
). This function is implemented on the google
namespace (i.e., google.setOnLoadCallback(callback);
)
.setOnLoadCallback()
has no return value.
Note: Previous documentation recommended that you use the body element's onload attribute (
). While this is a fine way to go when you are in complete control of the page and all code loaded by the page, this approach can cause problems with some runtimes that destroy your body.onload
handler. setOnLoadCallback()
does not have these problems, and therefore is the recommended method of registering a callback that calls your code when the API is fully loaded and ready for use.
.getBranding(opt_element?, opt_orientation?)
is a static helper function that returns a "powered by Google" HTML DOM branding node to your application, and optionally attaches it to your document as the only child of the specified optional element. The purpose of this method is to ensure that your application has a simple way to comply with branding requirements.
The branding node, by default, is designed for a horizontal orientation and works well underneath a search form, above or below a collection of results, etc.
opt_element
is an optional argument which, if supplied, specifies the HTML DOM node that will be populated with a "powered by Google" branding element.
opt_orientation
- an optional argument which, if supplied, specifies the orientation of the branding node. Valid values include:
google.search.Search.HORIZONTAL_BRANDING
requests horizontal orientation. This is the default behavior.
google.search.Search.VERTICAL_BRANDING
requests vertical orientation.
.getBranding()
returns a "powered by Google" HTML DOM node that you can attach or clone onto your document.
You must call .getBranding()
on google.search.Search
, not on google.search.LocalSearch
.
Warning! This API requires displaying attribution near any API input boxes and the display of results, indicating that it is "Powered by Google". If you choose not to use .getBranding(), you are obligated to provide this branding yourself.
.getAttribution()
provides an attribution node which is required to be displayed in line with Local Search results. The return value is an HTML node that should be added to each search result. The following snippet demonstrates how to incorporate .getAttribution
:
var attribution = google.search.LocalSearch.getAttribution(); if (attribution) { var el = document.getElementById("searchwell"); el.appendChild(attribution); }
Result objects are produced using a JSON encoding of server search requests. Consequently, we have chosen not to implement formal JavaScript objects, and instead dynamically create these objects from their serialized form.
While there is no formal implementation of the objects, they exist, and we document them as if there was a backing JavaScript implementation. The impact of all this is minimal. All that it means is that there is no named constructor. For each result, it's as if the system called new Object()
and then set formal properties on that object. These properties are documented below.
The Google Local Search API allows a maximum of 32 results on 4 pages. There is no way to get more than 32 results.
Here are the basic properties allowing you to handle results from the Local Search API.
| Property | Description |
|---|---|
|
|
Supplies an array consisting of the mailing address lines for this result, for instance: |
|
|
Supplies the city name for the result.
Note: If a city name is not available, this property may be set to |
|
|
For KML results, this property contains a content snippet associated with the KML result.
Note: For local results, set this property to |
|
|
Supplies a country name for the result.
Note: If the country name is not specified, set this property to |
|
|
Note: The Local Searcher supports a maximum of 8 result pages. When combined with subsequent requests, a maximum total of 64 results are available. It is not possible to request more than 64 results. |
|
|
Supplies a URL that you can use to provide driving directions from the center of the set of search results to this search result.
Note: If a |
|
|
Supplies a URL that can be used to provide driving directions to a search result from a user-specified location.
Note: In some cases, this property may be missing or null. Always wrap access within a a test of |
|
|
Supplies a URL that can be used to provide driving directions from this search result to a user-specified location.
Note: In some cases this property may be missing or null. Always wrap access within a a test of |
|
|
Indicates the type of result (for example, |
html
|
Supplies the root of an HTML element that may be cloned and attached somewhere into the application's DOM hierarchy. We expect that this is the primary property that applications will use, typically by cloning this node and attaching it to the DOM hierarchy. We expect applications to control styling, as well as which elements are displayed, using CSS. For instance, we expect the following fragment to be common across all applications that wish to copy and paste search results delivered through the Local Search API. // clone the .html node from the result var node = result.html.cloneNode(true); // attach the node into my dom |
|
|
Supplies the latitude value of the result. This may be used to construct a p = new GPoint(parseFloat(result.lng), parseFloat(result.lat)); |
|
|
This property indicates the type of this result, which can either be |
|
|
Supplies the longitude value of the result. This may be used to construct a p = new GPoint(parseFloat(result.lng), parseFloat(result.lat)); |
|
|
Supplies an array of phone number objects where each object contains a |
|
|
Supplies a region name for the result. In the US, the region name is typically a state abbreviation; in other areas it might be a province or other region name as locally applicable.
Note: If a region name is not available, this property is set to |
|
|
|
|
|
Supplies the URL for a static map image representation of the current result. The image is 150px wide by 100px tall with a single marker representing the current location. Expected usage is to hyperlink this image using the |
|
|
Supplies the street address and number for the given result.
Note: If no street address is available, this property is set to |
|
|
Supplies the title for the result. In some cases, the title and the |
|
|
Supplies the title, but unlike |
|
|
Supplies the URL to a Google Maps Place page associated with the search result. |
The .html
property discussed above is built with CSS styling in mind. As a result, each piece of semantic information is enclosed in HTML markup with an appropriate set of class markers. This allows you to use this HTML in conjunction with your own custom CSS rules that style the HTML to meet your needs.
The following fragment of HTML illustrates the structure of a Local Search result's .html
property. The purpose of this skeleton is to show you the major structural components work, so that you can alter the styling and display of a result. For instance, if you want to suppress the "snippet", a CSS rule of #mysearcher .gs-localResult .gs-snippet { display : none; }
would do the trick.
Each search result is enclosed in a div
element marked with a generic search result class of gs-result
, as well as a class specific to the result type (e.g., gs-localResult
). This structure allows you to easily define generic CSS rules that are applied to all results, as well as type-specific rules.

.setCenterPoint(location)
targets search results to a specific location, where location
supplies the location using one of three possible variants:
google.maps.Map2
in the presence of a getCenter()
property.
google.maps.LatLng
in the presence of an x
property.
string
which specifies an address by name. When this argument is presented, searches are scoped as if the user performed a Google Local Search specifying near location as part of their search expression. Note: The string location is resolved into a google.maps.LatLng
asynchronously so if this method is used, searches are made relative to this location once the geocoding operation completes with success.
If you do not specify this property, the default location is San Francisco, California.
The preferred interface is either google.maps.LatLng()
or google.maps.Map2()
.
.setCenterPoint(location)
has no return value.
By default, the Local Search API co-mingles address lookup results (e.g., NY, NY) with local search results. However, there are situations where this co-mingled approach is undesirable.
For instance, suppose the searcher is centered in Santa Barbara, CA and the user is searching for "Cava". With co-mingled results, the first search result is actually an address match against "Cava Close, Aberdeen City, AB15 UK". The second result is "Cava Restaurant & Bar". Disabling address lookup causes the desired "Cava Restaurant & Bar" to be the first result.
.setAddressLookupMode(mode)
allows applications to disable or enable address lookup, where mode
supplies the desired address lookup mode:
google.search.LocalSearch.ADDRESS_LOOKUP_ENABLED
enables address lookup producing co-mingled results. This is the default behavior.
google.search.LocalSearch.ADDRESS_LOOKUP_DISABLED
disables address lookup and only produces search result titles.
.setAddressLookupMode(mode)
has no return value.
.setRestriction(type, opt_value)
specifies or clears a restriction on the set of results returned by this searcher, where:
type
(required) has one possible value for local search: google.search.Search.RESTRICT_TYPE
.
opt_value
supplies the value for the specified restriction type, as follows:
google.search.LocalSearch.TYPE_LOCALONLY_RESULTS
returns only local listing results results and geocodes. This is the default behavior.
google.search.LocalSearch.TYPE_BLENDED_RESULT
returns a mix of both KML results and normal, local listings and geocodes.
google.search.LocalSearch.TYPE_KMLONLY_RESULTS
returns only KML results and geocodes.
To return the searcher to its default behavior, clear the restriction by calling this method with no opt_value
, as follows: .setRestriction(type)
.
.setRestriction(type, opt_value)
has no return value.
The following sample shows how to return only KML results:
localSearch.setRestriction(google.search.Search.RESTRICT_TYPE, google.search.LocalSearch.TYPE_KMLONLY_RESULTS)
.computeStaticMapUrl(results, height, width, opt_zoom?)
is a utility function that creates a static map image from the a collection of points specified as a collection of search result objects, objects containing a numeric .lat
and .lng
property, or google.maps.LatLng
objects. Only the first google.search.LocalSearch.STATIC_MAP_MAX_POINTS
objects are included. This function is defined as follows:
results
supplies an array of objects to be plotted on on a static map image.
height
supplies the height of the new image, in pixels (maximum height of 640 pixels). This field is required.
width
supplies the width of the new image, in pixels (maximum width of 640 pixels). This field is required.
opt_zoom
supplies an optional zoom level for the map. If not specified, the system computes an appropriate zoom level. If supplied, valid values include:
google.search.LocalSearch.STATIC_MAP_ZOOM_CLOSEST
google.search.LocalSearch.STATIC_MAP_ZOOM_FARTHEST
.computeStaticMapUrl(results, height, width, opt_zoom?)
returns a URL to the static map image.
The code sample below creates a static map image from a collection of locations in northern Europe (view live sample). This map displays by default when there are no search results. When a search completes, a new map image is computed using the collection of search results.
// demonstrate computeStaticMapUrl with simple point array this.worldPointsUrl = google.search.LocalSearch.computeStaticMapUrl( worldPoints,350, 400); document.getElementById("resultsImg").src = this.worldPointsUrl; ... var worldPoints = [ { lat : 48.8565, lng : 2.3509 }, // paris { lat : 52.5238, lng : 13.4119}, // berlin { lat : 52.3738, lng : 4.8909}, // amsterdam { lat : 55.676294, lng : 12.568115}, // copenhagen { lat : 60.160791, lng : 24.952548}, // helsinki { lat : 59.332725, lng : 18.064454}, // stockholm { lat : 59.913820, lng : 10.738741} // oslo ];
.resizeStaticMapUrl(result, height, width, opt_zoom?)
is a utility function that resizes the image associated with the staticMapUrl
property of the specified result. Upon completion, this property is replaced with a new value that represents the re-sized static map image. This function is defined as follows:
result
supplies the result object whose static map image is to be re-sized. Upon completion, the staticMapUrl
property of this result object is modified.
height
supplies the new image height, in pixels (maximum height of 640 pixels). This field is required.
width
supplies the new image width width, in pixels (maximum width of 640 pixels). This field is required.
opt_zoom
supplies an optional zoom level for the map, defined as follows:
google.search.LocalSearch.STATIC_MAP_ZOOM_DEFAULT
.
google.search.LocalSearch.STATIC_MAP_ZOOM_CLOSEST
defines the closest zoom
google.search.LocalSearch.STATIC_MAP_ZOOM_FARTHEST
defines the furthest zoom
.resizeStaticMapUrl(result, height, width, opt_zoom?)
returns the new value of the resized staticMapUrl
.
The Static Map Tile sample demonstrates one way to use this method (see the snippet below).
var img = document.createElement("img"); google.search.LocalSearch.resizeStaticMapUrl(result, 80, 120); img.src = result.staticMapUrl; img.title = result.titleNoFormatting;
.setResultSetSize(num)
specifies the size of the result set, where num
supplies the number of results to display per page, from 1-8.
.setResultSetSize()
has no return value.
.getResultSetSize()
has no arguments and returns an integer from 1–8 indicating the current result set size (which is established by .setResultSetSize()
. It allows you to determine the result set size returned by the search.
.createResultHtml(result)
allows the caller to either create or re-generate the .html
property of the specified result, where result
supplies a result object.
If the result has no .html
property, this call creates one. One circumstance requiring you to create an .html
property is if the caller had previously used .setNoHtmlGeneration()
.
.createResultHtml()
has no return value.
.clearResults()
resets the searcher, clearing all of the results of the previous search. This method is implicitly called prior to executing a new search.
.clearResults()
has no arguments and no return value.
.setNoHtmlGeneration()
stops your application from generating an .html
property, leaving you with only the raw properties valid in a result. This property is useful for optimizing your application, if you want to handle rendering of the results yourself.
.setNoHtmlGeneration()
has no arguments and no return value.
.cursor
is an optional property that is present once a search completes successfully. When present, the property specifies how an application can request additional search results for the current query term, the estimated result count, the current page, and the URL for a search results page. The property has the following structure:
pages[]
supplies an array used by start
in order to iterate through all available results. Each entry in the array is an object with the following structure:
start
supplies the value that will be used in the &start
URL argument to request a bundle of results
label
supplies a text label associated with the entry (for example, "1", "2", "3", or "4")
estimatedResultCount
supplies the estimated number of results that match the current query. This value will not necessarily match the similar value that is visible on the Google.com search properties.
currentPageIndex
supplies the index into the pages
array of the current set of results.
moreResultsUrl
supplies a URL to a Google-hosted search page that contains additional search results.
Note: The Local Searcher supports a maximum of 4 result pages. When combined with subsequent requests, a maximum total of 32 results are available. It is not possible to request more than 32 results.
.gotoPage(page)
requests a specific page of search results after an initial search completes, where page
supplies the page number of the results that the application wants. Numbering of results pages begins at 0, and the searcher returns the first page by default.
If you specify a page number that is out of range, or if the underlying searcher has no .cursor
property, no operation is performed.
.gotoPage()
has no return value.
.results[]
contains an array of search result objects, one for each result. Each time a search executes, this property is cleared, and each time a search completes, the array is populated. If there are no results to report, the .length
property of this array will be set to 0. Therefore, results will never be null, and you can always safely check for results.length == 0
.
GlocalResult
object is produced by google.search.LocalSearch
. It is available in that object's .results[]
array.
.GsearchResultClass
value of google.search.LocalSearch.RESULT_CLASS
.
If you encounter problems with your code:


gzip file[:digit:]*.txt
gzip file[[:digit:]]*.txt
Predefined character groups are supposed to be used inside character ranges. [:digit:]
matches one of "digt:" just like [abc]
matches one of "abc". [[:digit:]]
matches a digit.
When passing an argument to tr
which parses these by itself without relying on globbing, you should quote it instead, e.g. tr -d '[:digit:]'


Ballerina 0.990.0 consists of significant improvements of the language syntax, which is based on a new specification.
Implicit variable initialization has been removed. Therefore the code int a; io:println(a);
that was valid in the previous release will fail with an error: variable 'a' is not initialized
.
Variables must be initialized explicitly before using them. For more information, refer to variable initialization in the What’s new section.
The match
statement no longer selects a block
statement or an expression to execute based on which pattern a type matches. Now it selects a block
statement based on the patterns a value matches. For more information, refer to the match statement section.
The but
expression has been removed. You can use type tests instead. For more information, refer to the structural types section.
The error type is no longer a built-in record type. Therefore, you will see syntax errors for error literals in the form of {message: “error message goes here”, cause: e}
. From this release onwards, the error type is a structured basic type used only for representing errors. It contains a reason; a string identifier for the category of error, a detail; a frozen mapping providing additional information, and a stack trace. For more information, refer to the error handling section.
The any
type no longer includes the error
type. The any
type is now a union of all types except error
type (and its subtypes). This change forces errors to be documented explicitly, even if a function returns any.
The map
type without type parameter is not allowed from this release onwards. The same applies to future
and stream
types. For more information refer to the structural types section.
The try-catch-finally
and throw
statements have been removed from this release. It encourages exception handling mechanism available in languages such as Java, JavaScript, and C++ where they allow mixing both normal errors (which programmers must be aware of and handle) and abnormal errors (which cannot be dealt with and often indicates a program error). For more information, refer to the error handling section.
The check
expression semantics has been changed to not throw an error if return
type of the enclosing function or resource does not contain the error
type.
The self
keyword has been mandated to access object members within the object definition. The following code will not compile with this Ballerina version.
type Person object {
private string name;
function getName () returns string {
return name;
}
};
Now you need to use self
when referring to object members as follows.
type Person object {
private string name;
function getName () returns string {
return self.name;
}
};
Object constructor syntax has been changed from this release onwards. Here is the old syntax.
type Person object {
private string name;
new (name) {
}
};
Here is the new syntax. With this change, we have removed the special signature in the constructor that existed in the previous release.
type Person object {
private string name;
function __init (string name) {
self.name = name;
}
};
For more information, refer to the object constructor redesign section.
An object method can be defined outside of the object definition given that it is not an abstract object and the object method is declared inside the object definition. The qualified name of the method defined outside is composed of the object type name and the method name. The previous syntax was object-type-name::method-name
and the new syntax is object-type-name.method-name
.
Endpoints and services are the key abstractions in Ballerina that bring network programming to a higher level of abstraction when compared to traditional languages. There are two kinds of endpoints: listener endpoints and client endpoints. We have changed the listener (inbound) endpoint variable definition syntax. Here is the old syntax.
endpoint http:Listener httpEp {
port: 9095
};
Now listener endpoints are Ballerina objects that implement the abstract listener object. Therefore, you can create a new instance of a module-level listener endpoint as follows. For more information, refer to endpoints and services section.
listener http:Listener httpEp = new (9095);
The service and resource definition syntax has been changed. Here is the old syntax.
service hello bind httpEp {
hi (endpoint caller, http:Request req) {
_ = caller->respond("Hello, World!");
}
}
Now services are first-class values and are like singleton objects. Resource definition has been modified slightly. Now a resource definition looks like a function definition with the resource qualifier. For more information, refer to standard library syntax section.
service hello on httpEp {
resource function hi (http:Caller caller, http:Request req) {
_ = caller->respond("Hello, World!");
}
}
The syntax of defining client endpoints (outbound endpoints) has been simplified. For more information, refer to the standard library syntax section.
The annotations @final
and @readonly
have been removed from this release onwards. Now you can declare final variables using the final
keyword. For example, final int port = readPortFromConfig();
.
The @doc
annotation that was deprecated in previous releases has been removed from this release onwards.
The syntax and semantics of functions calls and workers defined in the function body has changed. For more information, refer to the concurrency section.
The fork/join
statement has been removed. You can use the new fork
statement to start multiple workers in parallel with each other. Each worker name becomes a variable of type future<T>
where T is the return type of the worker. You can use the new wait
action to wait for one or more workers. For more information on the fork statement, wait action, and other concurrency-related changes, refer to the concurrency section.
The done
statement has been removed. Now workers can return values using the return
statement. For more information, refer to the concurrency section.
The await
statement has been replaced by the new wait
statement. For more information, refer to the concurrency section.
The foreach
statement has been changed in a consistent way to match with type binding patterns. Here is the old syntax.
map<Student> class = { ... }
foreach name, std in class {
string msg = name + " details: ";
io:println(msg, std);
}
Now the foreach
statement allows the value to be destructured, while iterating over a sequence. Here is an example.
foreach (string, Student) (name, std) in class {
string msg = name + " details: ";
io:println(msg, std);
}
Additionally, list
type iteration provides only the value as an argument. It no longer gives the index variable as the first argument. JSON is no longer iterable, instead, use array of JSON (json[]
) or map of JSON (map<json>
). For more information, refer to the [binding pattern section].
Iterable Operations (foreach
, map
, filter
) signatures have been changed to be consistent with the foreach
statement arguments.
This release contains significant changes and new features in areas such as structural types, error handling, concurrency, objects, and endpoints.
Ballerina has a structural type system in which compatibility of types and values is determined based on their structure; this is particularly useful in integration scenarios that combine multiple, independently-designed systems. The following changes to the Ballerina type system encourage data-oriented thinking, provides the foundation for safe concurrency by introducing immutable values, makes structural types, and mutability work together smoothly.
Ballerina programs use types to categorize values both at compile-time and runtime. Types deal with an abstraction of values, which does not consider storage location or mutability. This abstraction is called a shape.
A type denotes a set of shapes. A type S is a subtype of type T if the set of shapes denoted by S is a subset of the set of shapes denoted by T.
Every value has a corresponding shape. Since shapes do not deal with storage location, they have no concept of identity; shapes therefore represent trees rather graphs. Shapes differ from values only for reference values. For simple values, there is no difference between a shape and a value; the shape of a simple value is just that value. A shape is specific to a basic type: if two values have different basic types, they have different shapes.
There are two important relations between a value and a type:
For an immutable value, looking like a type and belonging to a type are the same thing.
When a Ballerina program declares a variable to have a compile-time type, this means that the Ballerina compiler together with the runtime system will ensure that the variable will only ever contain a value that belongs to the type. Ballerina also provides mechanisms that take a value that looks like a type and use it to create a value that belongs to a type.
A container has an inherent type, which is a type descriptor that is part of the container’s runtime value. At runtime, the container prevents any mutation that might lead to the container having a shape that is not a member of its inherent type. Thus, a container value belongs to a type if and only if that type is its inherent type or a subset of its inherent type.
A value is considered as a pure value if it is a simple value (nil
, boolean
, int
, float
, string
) or a structured value that contains only pure members. Error values are also considered as structured values.
The anydata
type consists of pure values whose basic
type is not error
. Thus (anydata|error)
contains all pure values. So anydata
is equivalent to () | int | float | decimal | string | (anydata|error)[] | map<anydata|error> | xml | table
.
Ballerina records are by default open. In the previous release, record {}
means record { any … }
. With the introduction of pure values now record {}
means it is open only to pure values.
Performs a deep copy of a pure value. It is a no-op operation on simple values and error values. This operation is guaranteed to succeed on pure values and preserves cycles, inherent type, and immutability of values.
Record type referencing is a mechanism for copying the fields from one record type descriptor into another record type descriptor. It is equivalent to defining those fields in the new type descriptor. If the fields have explicit default values specified, those values will be copied as well.
type Person record {
string name;
int age = 25;
!...
};
type Employee record {
*Person; // Referencing the `Person` record
string company;
string designation;
!...
};
The above Employee type descriptor is equivalent to the following type descriptor:
type Employee record {
string name;
int age = 25;
string company?;
string designation;
!...
};
From this release onwards, we have changed the semantics of operator ==
to perform a deep value equality only on anydata
values. A compile time error occurs if used for some other purpose. This operator is not allowed on error values.
We have introduced a new operator ===
that performs reference equality on reference types and is otherwise same as ==
. The !==
operator results in the negation of the result of the ===
operator.
We have introduced immutable values from this release onwards. Immutability is not part of the static type system in the language. It exists only in the runtime. You can use the freeze
built-in method to make a structured value frozen at runtime. This method sets the frozen
flags in the value. A frozen
structured value cannot be modified afterward and any such attempts will results in panics.
The freeze
built-in method changes the value to which it is applied to be frozen and returns that value. It works in a similar way to the clone
method.
There is a isFrozen()
built-in method on all structural basic types that returns true
or false
depending on whether the value is frozen.
person p1 = {name:"John", age:34};
person p1Frozen = p1.freeze();
boolean b = p1 === p1Frozen; // true
The type test can be used to determine whether a value is of a particular type.
int|string x = getValue();
if x is string {
// x is now string after implicit narrowing
return;
}
// x is now int
Type assertions can be used to assert the inherent type of a value. Assertion fails and results in a panic, if the asserted type is not exactly the storage type.
Employee e = { ... };
Person p = e;
Employee e2 = <Employee> p; // successful since storage type is Employee
Person p2 = <Person> p; // panics since storage type is Employee
The existing match has been changed in this release from a type match to a value match statement. The match statement is a value switching construct that allows selective code execution based on the value of the expression that is being tested.
match variable {
“Bal” => io:println(“Matched a String with value Bal”);
0 => io:println(“Matched an int with value 0”);
10 => io:println(“Matched an int with value 10”);
(15, “Lang”) => io:println(“Matched a tuple with (15, “Lang” values”);
false => io:println(“Matched a boolean with value false”);
{a: 15, b: “Lang”}=> io:println(“Matched a mapping value”);
_ => io:println(“Matched to Default Pattern”);
}
The match
statement can also be used to match the structure of a value by using binding patterns. The matched value will be destructured to new variables within the scope of the match pattern. Here is an example of the structured value match.
match variable {
var (var1, var2) => { // match a tuple value with two members
io:println(var1);
io:println(var2);
}
var {a: var1, b: var2} => { //match a mapping value with fields “a” and “b”
io:println(var1);
io:println(var2);
}
var x => io:println(“Matched to Default Pattern”); //all values will match
}
There are two types of relationships between a value and a type in this section. They are ‘looks like’ and ‘belongs to’. With the introduction of these two relationships, one might want to transform a value that looks like a type into a value that belongs to that type. We have introduced two built-in methods to do that.
T.stamp(v)
: Mutate the value v itself and set its inherent type to T.T.convert(v)
: Make copy of the value v and set its inherent type to T.Ballerina distinguishes two kinds of errors; normal and abnormal errors. Abnormal errors are unusual occurances and they are usually signs of bugs or programmer errors. It is usually not possible to recover from abnormal errors. Normal errors, on the other hand, are recoverable and they are part of your business logic.
Normal errors can be returned from functions, workers and resources hence have an explicit control flow. They are also statically type checked. Abnormal errors stop the execution of a program unless they are trapped: implicit control flow. Following changes and improvements defines consistent policy on error handling throughout the language. Also, these changes have an impact on concurrency features which is explained in the concurrency section.
The error type is a structured basic type which is used only for representing errors. A value of error type contains a reason which is a string identifier for the category of error, a detail which is a frozen mapping providing additional information and a stack trace. Error values are made immutable from this release onwards, since they can propagate across concurrent execution blocks. Allowing them to be mutable can be dangerous.
Here is an example for usage of error type. The function getAcctBalance
returns a union of decimal
and error<string, AccountData>
types.
type AccountData record {
string accountID;
};
function getAcctBalance(int id)
returns decimal | error<string, AccountData> {...}
The any
type was the union of all types in Ballerina. However, from this release onwards, we have removed the error
type from any
. This change forces errors to be documented explicitly, even if a function returns any
.
The check
expression is a useful unary operator in the language, which allows you to get an error out of the way in arbitrary expressions. If the type of the expression E is T | error
, then the type of expression check E will be T
if it evaluates to T
. If the expression evaluates to error, then the function terminates immediately as if by return E
. The check
operator forces you to declare error as part of the return type of your function.
In the previous release, check throws the error if the function does not have error type as part of the return
type. This causes normal errors to become exceptions or abnormal errors due to negligence of the programmer.
Here is a sample usage of check operator.
function startHTTPListener() returns Listener | error {
string strVal = getValue(HTTP_PORT);
// int.convert() has the type 'int | error'
int port = check int.convert(strVal);
...
}
This is a replacement for the throw
statement to allow programmers to create a panic, which causes the execution to stop. Function calls will unwind until the panic is stopped by trapping it and converting it into an error. Stack trace is recorded in the error value at the time of panic.
int | error i = int.convert("4t4");
if i is error {
panic i;
}
The trap
expression stops a panic and gives access to the error value associated with the panic. This is a replacement for the try-catch
statement. In var a = trap E
, the type of the variable a
will be T | error
where T
is the type of the expression E
.
Binding patterns are used to support destructuring, which allows different parts of a single structured value each to be assigned to separate variables at the same time. Binding patterns can be used both with or without a type. Using a typed binding pattern
will assign the destructured values to new variables, while a destructure assignment binding pattern
will assign the destructured values to existing variable references.
This release introduces two binding patterns; tuple binding pattern and record binding pattern.
Tuple binding pattern destructures a tuple
value based on the number of members in the tuple
value. Here is an example of a tuple binding pattern.
(int, string) tupleVar = (20, “Ballerina”);
(int, string) (intVariable, stringVariable) = tupleVar; //typed binding pattern
io:println(intVariable + “ “ + stringVariable);
int intVariable2;
string stringVariable2;
(intVariable2, stringVariable2) = tupleVar; //binding pattern with variable references
io:println(intVariable2 + “ “ + stringVariable2);
Record binding pattern destructures a mapping value based on the presence of a field name. Here is an example of a record binding pattern. In this example a Person
typed record with fields name
and age
will be destructured. The variable name to which the value is to be assigned can be given against a field name following a colon. Omitting a variable name will result in using the same name as the field name.
Person {name, age: personAge} = getPerson(); //typed binding pattern
io:println(name + “ “ + personAge);
string personName;
int age;
{name: personName, age} = getPerson(); //binding pattern with variable references
io:println(personName + “ “ + age);
Ballerina has built in support for concurrency. worker
and start
creates new concurrent flows. wait
, ->
(send), <-
(receive), and ‘flush’ constructs offer flow control and communication between concurrent flows. lock
construct can be used to achieve safe concurrent access.
Ballerina execution model is based on ‘strands’ that are lightweight execution flows. Strands may run parallely and scheduled by the runtime. Strands are represented by futures
in the language.
Start executes a given function in a new strand, resulting a new future
. This future
can be used to interact with the concurrent execution flow.
Workers offer a way to write a concurrent code section inline within an existing function.
A function has one or more workers including an unnamed default worker and other named workers. These workers are peers of each other. The termination of the function is independent of the termination of its named workers. Returning from a named worker terminates that worker, but does not cause a return from the function. Workers have same return declaration as functions which defaults to ()
The workers created by a fork
statement are peers of each other: they can exchange messages with each other but not with any other workers. In other respects, workers created by a fork
statement behave the same as workers created by a function body.
A future
is just a worker that can be waited for outside the function that starts the worker.
A wait-action waits for one or more futures to be terminated and makes available their return value (including any raised errors). Panic in waited-for future should result in panic in wait
. Waiting for a future and waiting for a worker are conceptually the same.
Using the future you can (a) cancel the strand (b) wait for the strand return.
Send/sync-send will send anydata
type information to another worker, in which receive
can be used in the other worker to retrieve the message. Compile time analysis guarantees there is a matching receive for each send.
If the data is not available, receive will wait, similarly if the receiver is not reached yet, the sync send will wait. Both sync send and receive will propagate whichever error that happened in the opposing strand to the current strand.
flush
will wait until all the messages are sent from the current worker to the specified worker. If the receiver failed or panicked, then that error will be propagated to the waiting strand.
Lock can be used to make the concurrent access safe for a set of variables. It creates two phase deadlock-free synchronization guaranteeing unique access to each variable.
public function invokeWorkers() returns int {
worker w1 {
int i = 5;
i -> w2;
}
worker w2 returns int {
int j = <- w1;
return j;
}
return (wait w2) + 1;
}
A compile-time constant is a typed identifier whose value is computed at compile time. Compile time reference values are frozen
values.
const i = 10;
The modified final
variable can be applied to a variable declaration to mean that the variable cannot be modified after it has been initialized.
final int port = getValue();
// Here the type is inferred from the right-hand side expression.
final var addr = getAddr();
In Ballerina, endpoints represent an external system that one or more workers interact with. There are two types of endpoints, Listener endpoints or client endpoints.
Previously, both these endpoints were modeled using two object definitions. One defined the life cycle of the endpoint, other defined the actions of the endpoint. Additionally, the endpoint keyword was used to represent endpoint instances and it had its own initialization and assignment syntax.
With this release, the endpoints are declared as client objects. Also, the following are removed from the language.
endpoint http:Listener helloWorldEP { port : 9090 }
An object that has a client modifier is a client object type. A method on a client object can have a remote modifier; a method with a remote modifier is called a remote method. A remote method can be called only using a remote method call
. E.g., clientObj->remoteFunctionName (arguments)
. This is previously called action invocation
.
E.g.:
public type Twitter client object {
public remote function tweet (string message) returns error? { ... }
};
A Client Object variable declaration is allowed only in following places - module level as a module level variable. - in a function initialization (before any worker declarations or statements). - as an argument to the function.
Eg:
Twitter globalClient = new;
public function tweetSomething(Twitter paramClient) {
Twitter localClient= new;
worker w1 {
_ = localClient->tweet("tweeting from local client.");
}
worker w2 {
_ = paramClient->tweet("tweeting from param client.");
}
_ = globalClient ->tweet("tweeting from global client");
}
A listener is an object that implements the abstract listener object. It defines the life cycle of the listener.
public type AbstractListener abstract object {
public function __start() returns error?;
public function __stop() returns error?;
public function __attach(service s, map<any> annotationData) returns error?;
};
A module listener is a Listener object that is managed as part of the module’s lifecycle. It is like a final global variable but registers itself with the module life cycle. So a module starts all its module listeners after all services have been attached the listeners and stops the listeners when the module stops. Module listeners are created as follows.
listener http:Listener httpEp = new (9095);
Module Listeners can be attached to module service. With this change, the old endpoint declaration and endpoint bind syntax have been removed from the language.
There is a new basic type of behavioral value called service
, which represents a named collection of resource functions. A type-descriptor service
contains all values of basic
type service.
Precise service typing is not provided in this version of Ballerina. This will be added in future versions.
A service value can be constructed using the service constructor expression.
Eg:
service myService = @http:ServiceConfig { basePath : "/hello"} service {
resource function hi (http:Caller caller, http:Request request ) {
_ = caller -> respond(self.getHelloWorld());
}
function getHelloWorld() returns string {
return "hello world ...!";
}
};
resource
qualifier is used to represent the resource methods of the service. Resource methods cannot be called using the method call
expression. They are intended to invoke in response to an incoming network request. A service’s non-resource methods can be called using a method call expression.
A module service is a syntax for creating service value at the module level. A module service must have one or more module listeners or anonymous module listeners (created using type new expression) attached. Here is the syntax.
listener http:Listener httpEp = new (9095);
@http:ServiceConfig { basePath : "/hello"}
service MyService on httpEp, new http:Listener (9085) {
resource function hi (http:Caller caller, http:Request req) {
_ = caller->respond("Hello, World!");
}
}
MyService
is a service value, which is attached to both httpEP listener
and the new HTTP module Listener. Previously this was referred as a services name, now it is a final module service variable.
Above code is a syntactic sugar and equal to the following code, which runs at module init time.
http:Listener httpEp = new http:Listener(9085);
service MyService = @http:ServiceConfig { basePath : "/hello"} service {
resource function hi (http:Caller caller, http:Request req) {
_ = caller->respond("Hello, World!");
}
};
check httpEp.attach(MyService ); // if fails, module init fails.
http:Listener anonEP = new http:Listener(9085);
check anonEP.__attache(MyService);
check httpEp.__start();
check anonEP.__start();
Decimal type is a basic, simple type in Ballerina. The decimal type corresponds to the 128-bit IEEE 754-2008 decimal (radix 10) floating point number format. A decimal value has 34 decimal digits of significand and an exponent range of −6143 to +6144.
decimal d = 4.565;
Defining a decimal variable is very similar to defining a float variable in Ballerina By default, all the floating point literals will be treated as float values unless otherwise we explicitly state as decimal
Requirements:
To represent high precision and high scale numbers
Current float type (64 bits) may not be adequate in certain cases
Financial and commercial use cases
Currency representations
To resolve floating point precision error problem exists in float type
Floating-point numbers cannot precisely represent all real numbers
Hence, it leads to many erroneous results when performing arithmetic operations
For example, the below boolean expression would result false when the numbers are represented using float type
0.1 + 0.2 == 0.3
// Above would result false
if the numbers are represented using float
This is because of the non-representability of 0.1 (0.0001100110011..) and 0.2 (0.001100110011..) in binary
IEEE 754-2008 Decimal128 format resolves this problem by treating the radix 10 when representing the values
You can unlock experimental language features with the --experimental
flag.
oncommit
and onabort
function handlers are removed from the transaction statement and are substituted with committed and aborted blocks.
transaction with retries = 2 {
_ = testDB->update("Insert into Customers (firstName,lastName,registrationID,creditLimit,country)
values ('James', 'Clerk', 200, 5000.75, 'USA')");
_ = testDB->update("Insert into Customers (firstName,lastName,registrationID,creditLimit,country)
values ('James', 'Clerk', 200, 5000.75, 'USA')");
} onretry {
returnVal = -1;
} committed {
committedBlockExecuted = true;
} aborted {
abortedBlockExecuted = true;
}
Functions and resource functions can be marked as transaction participants using @transactions:Participant {} annotation from the transactions module. This annotation facilitate registering handler functions that are triggered when the transaction initiator commit or abort.
And panic propagating out of such participant is considered as transaction participant failure when deciding to commit the transaction.
With this introduction of transaction participants, nesting transaction blocks are prohibited, both statically and at runtime.
@transactions:Participant {
oncommit:commitFunc,
onabort:abortFunc
}
public function participantLocal() {
string trxId = transactions:getCurrentTransactionId();
io:println("In transaction participant of: " + trxId);
// Simulate participant failure.
error e = error("An error");
panic e;
}
The above code will cause the calling transaction to fail due to the panicking of a participant.
If the participantFoo is called without a transaction, all the transaction related annotations will be ignored for that particular call.
oncommit
and onabort
functions should have the signature of function (string trxId)
Similar to local transactions we can also annotate resource functions so that they are considered transaction participants. Annotated transaction participants are not allowed to have transaction blocks similar to local participants.
Panic in remote participants will result in transaction failure.
@transactions:Participant {
oncommit:commitFunc,
onabort:abortFunc
}
resource function participantRemote(http:Caller ep, http:Request req) {
Database(ep, req, false);
}
With endpoints and service syntax changes, HTTP endpoint and service are changed as follows:
HTTP Listener:
listener http:Listener httpEp = new(9090, config = {
secureSocket: {}
});
Note: Listener endpoint port is the first argument which is a required parameter and other listener configurations go under the second argument.
Service and resource definition:
service hello on httpEp {
resource function sayHello(http:Caller caller, http:Request req) {
_ = caller->respond("hello ballerina!");
}
}
Service can get attached to a listener endpoint that is declared inline as follows.
service hello on new http:Listener(9090) {
//...
}
Client endpoint:
http:Client clientEndpoint = new("https://localhost:9092", config = {
secureSocket: {}
});
Note: URL is the first argument which is compulsory and other endpoint configurations go under the second argument.
The Load Balancer exposes an abstract object to allow users to customize the routing decision making(load balancing rule) for special purposes. Only one rule is active at any time and it is specified with the lbRule in the LoadBalanceClientEndpointConfiguration
record. By default, round robin rule is used as the load balancing strategy.
Load balancer client endpoint syntax goes as follows.
http:LoadBalanceClient customLoadBalanceClient = new ({
targets: [
{ url: "http://localhost:8081/mock" },
{ url: "http://localhost:8082/mock" },
{ url: "http://localhost:8083/mock" },
],
lbRule: customLbRule
});
TCP server and client are completely redesigned with this release. Now users can use the TCP server similar to the WebSocket listener where there are set of predefined resources to invoke based on actions that take place. TCP client can be used to connect to a remote TCP server for data sending purpose. Additionally, callback service can be attached to the client if there is a data retrieval use case.
import ballerina/socket;
Listener:
listener socket:Listener server = new ({ port:<PORT_NUMBER> });
service echoServer on server {
resource function onAccept (socket:Caller caller) { }
resource function onReadReady (socket:Caller caller, byte[] content) { }
resource function onClose(socket:Caller caller) { }
resource function onError(socket:Caller caller, error er) { }
}
Client:
socket:Client socketClient = new({host: "localhost", port: 54387, callbackService: ClientService});
byte[] payloadByte = “Hello Ballerina”.toByteArray("UTF-8");
_ = socketClient->write(payloadByte);
service ClientService = service {
resource function onConnect(socket:Caller caller) { }
resource function onReadReady (socket:Caller caller, byte[] content) { }
resource function onClose(socket:Caller caller) { }
resource function onError(socket:Caller caller, error er) { }
};
socket:Client/socket:Caller
has shutdownRead
and shutdownWrite
functions available in addition to the write.
MySQL client syntax is changed as follows.
mysql:Client testDB = new({
host: "localhost",
port: 3306,
name: "testdb",
username: "root",
password: "root",
poolOptions: { maximumPoolSize: 5 },
dbOptions: { "useSSL": false }
});
Compile time validation for InMemory, Server and Embedded Mode configurations are introduced along with the changes in client syntax changes.
Creating a client in H2 Embedded Mode
h2:Client testDB = new({
path: "/home/ballerina/test/",
name: "testdb",
username: "SA",
password: "",
poolOptions: { maximumPoolSize: 5 }
});
Creating a client in H2 Server Mode
h2:Client testDB = new({
host: "localhost",
port: 9092,
name: "testdb",
username: "SA",
password: "",
poolOptions: { maximumPoolSize: 5 }
});
Creating a client in H2 In-Memory Mode
h2:Client testDB = new({
name: "testdb",
username: "SA",
password: "",
poolOptions: { maximumPoolSize: 5 }
});
gRPC is a protocol that is layered over HTTP/2 and enables client and server communication by combination of any supported languages. In gRPC, a client application can directly call methods on a server application on a different machine, making it easier for you to create distributed applications and services.
With endpoints and service syntax changes, gRPC endpoint and service are changed as follows:
Listener (inbound) endpoint:
listener grpc:Listener grpcEp = new (9095, config = {
secureSocket: {}
});
Note: Listener endpoint port is the first argument and other listener configurations go under the second argument.
Service and resource definition:
service Hello on grpcEp {
resource function hi (grpc:Caller caller, string req) {
_ = caller->send("Hello, World!");
}
}
Client endpoint:
HelloClient helloEp = new("https://localhost:9090", config = {
secureSocket: {}
});
Note: Server URL is the first argument and other endpoint configurations go under the second argument.
The contract first approach was introduced for gRPC service creation, which means you first define the service contract (.proto file). From the service contract, you generate stub and sample Ballerina service using the built-in proto compiler. Earlier we followed a code first approach to create a gRPC service, but we depreciated it due to a limitation in ensuring backward compatibility. Instead we recommend contract first approach to create a gRPC service.
With endpoints and service syntax changes, WebSocket endpoint and service are changed as follows:
WebSocket Listener:
listener http:WebSocketListener helloListener = new(9095, config = {secureSocket: {}});
service onTextString on helloListener {
resource function onText(http:WebSocketCaller caller, string data, boolean finalFrame) {
var returnVal = caller->pushText(data);
}
}
WebSocket Client:
http:WebSocketClient wsClientEp = new(REMOTE_BACKEND_URL, config = { callbackService: clientService });
service clientService = @http:WebSocketServiceConfig {} service {
resource function onText(http:WebSocketClient caller, string text) {
var returnVal = caller->pushText(data);
}
}
WebSub endpoint and service are changed as follows with the new endpoints and service syntax change
Listener:
listener websub:Listener websubEP = new(8181);
Service and resource definition:
service websubSubscriber on websubEP {
resource function onNotification(websub:Notification notification) {
log:printInfo("WebSub Notification Received");
}
}
WebSub Hub start up function signature is improved to accept parameters under two categories.
It accepts an http:Listener
, on which the hub service will start on, as the first parameter,
and a HubListenerConfiguration
record as a defaultable parameter to specify hub related configuration.
var webSubHub = websub:startHub(new http:Listener(9090), hubConfiguration = {
leaseSeconds: 86400
});
Improved the hub client by extending configuration to have the complete functionality of the HTTP Client.
http:ClientEndpointConfig conf = {
followRedirects: { enabled: true, maxCount: 5 }
};
websub:Client websubHubClientEP = new("https://localhost:9191/websub/hub", config = conf);
The ballerina/jms
module provides an API to connect to an external JMS provider like Ballerina Message Broker or ActiveMQ. This module provides different consumer and producer endpoint types for queues and topics. The endpoints prefixed with “Simple” will automatically create a JMS Connection and a JMS Session when the endpoint is initialized. For other endpoints, the developer must explicitly provide a properly initialized JMS Session.
New syntax for JMS message producer and message receiver is as shown below.
Note: JMS Connection and session definitions remain unchanged.
jms:Connection conn = new({
initialContextFactory:<provider specific initial context factory>,
providerUrl: <provider url>
});
jms:Session jmsSession = new(conn, {
acknowledgementMode: "AUTO_ACKNOWLEDGE"
});
JMS message producer definition:
jms:QueueSender queueSender = new({
session: jmsSession,
queueName: "MyQueue"
});
JMS message receiver, service, and resource definition:
listener jms:QueueReceiver consumerEndpoint = new({
session: jmsSession,
queueName: "MyQueue"
});
service jmsListener on consumerEndpoint {
resource function onMessage(jms:QueueReceiverCaller consumer, jms:Message message) {
}
}
Added test generation code action for services and functions.
API Designer view was added to edit/design HTTP APIs. Use “Show API Designer” command to activate API Design view in VSCode.
Language Core introduces experimental features and in order to support code intelligence such as auto completion in VSCode Plugin. Enable the Allow Experimental
setting in the user settings to experience this.
The ballerinax/kubernetes
module now supports generating Istio gateways and Istio virtual services for Ballerina services. These artifacts can be generated with @kubernetes:IstioGateway
and @kubernetes:IstioVirtualService
annotations, which allow to deploy services seamlessly to Istio.
All artifacts are now generated into a single YAML file by default. This can be overridden by setting singleYAML: false
in the @kubernetes:Deployment
annotation.
Please refer Ballerina performance test results available in the repository.
Please refer to GitHub milestone issues to view bug fixes
Use of “null” value in a non-JSON related context is not restricted yet. An array that contains a nil value has an invalid string representation.
Binary Literal are allowed as an integer literal. But it is not part of the 0.990.0 language specification. This support to be removed from the Compiler in future.
Two NaN values with different bit patterns are not considered as same at the runtime, but the specification mentioned otherwise. In Decimal implicit initial value taken as “0” instead of “+0.0” For floating point, === means the same member of value space. For example, NaN === NaN, -0.0 !== +0.0 But this validation gives incorrect results at runtime.
String values are not iterable in this release.
A Required field of a record can have a default value. But 0.990.0 language specification does not allow default values. If a record mapping constructor doesn’t have a value given for such field, then the default value is taken.
Table values are not iterable using foreach statement.
Detail value of an error is not frozen.
The runtime implementation doesn’t enforce the “detail” value of an error to be a subtype of map<anydata|error>
.
In an XML sequence, a character set is treated as a single string. However, in the specification, each character item is represented by a string with a single code point.
Error handling in the object initialization method is not supported yet. Only nil returning __init
methods are allowed.
This prevents using “check” expression inside the object initialization function.
Similar to record fields, an Object field can have a default value. Built-in Iterator, Iterable, and Collection abstract object type are not supported yet.
Runtime allows float values as a singleton type.
Defining a variable with singleton type is not allowed. E.g., 5 a = 5
In the implementation, a structured value that contains an error value is not considered as “anydata”.
An integer constant reference can’t be used to define the length of an array.
The compiler doesn’t do data flow analysis for frozen value. This results in a panic at run-time if a value is updated after a freeze.
'freeze()
and isFrozen()
are not allowed on nil value.
Falling off an end of a function body will not implicitly return () if the function returns an optional type. Explicit return () statement is required.
In this release, const
support is only added for boolean
literals, int
literals, floating point literals, and string
literals.
The current implementation uses different interpolation syntax {{expr}}
instead of ${expr}
in string templates. Decimal division and remainder operations panic if the second operand is 0.0;
.
Iiterator, unfrozenClone, and stackTrace built-in methods are not supported yet.
Error binding pattern is not supported in this release.
You can download the Ballerina distributions, try samples, and read the documentation at https://ballerina.io. You can also visit the Quick Tour to get started. We encourage you to report issues, improvements, and suggestions at the Ballerina Github Repository.