Apidays New York 2024 - The value of a flexible API Management solution for O...
The Ring programming language version 1.5.1 book - Part 38 of 180
1. Ring Documentation, Release 1.5.1
Just imagine what will happens to the world of programming once
we create many powerful frameworks using the Ring language that
uses this way (Natural Programming).
For example When we say Hello to the Machine, It can reply! and when we
say count from 1 to 5 it will understand us, Also if
we said count from 5 to 1 it will
understand us too! You can see the Output window!
This Goal is not new, but the Ring language comes
with an innovative solution to this problem.
Output:
Hello, Sir!
The Numbers!
1
2
3
4
5
I will count Again!
5
4
3
2
1
To execute the natural code, We have start.ring
In start.ring we define the language and the commands.
File: start.ring
load "stdlib.ring"
load "naturallib.ring"
New NaturalLanguage {
SetLanguageName(:MyLanguage)
SetCommandsPath(CurrentDir()+"/../command")
SetPackageName("MyLanguage.Natural")
UseCommand(:Hello)
UseCommand(:Count)
RunFile("program.txt")
}
We defined a language called MyLanguage, We have folder for the language commands.
46.1. Natural Library - Demo Program 345
2. Ring Documentation, Release 1.5.1
Each command will define a class that belong to the MyLanguage.Natural package.
We will define two commands, Hello and Count.
So we must have two files for defining the commands in the CurrentDir()+”/../command” folder
File: hello.ring
DefineNaturalCommand.SyntaxIsKeyword([
:Package = "MyLanguage.Natural",
:Keyword = :hello,
:Function = func {
See "Hello, Sir!" + nl + nl
}
])
File: count.ring
DefineNaturalCommand.SyntaxIsKeywordNumberNumber([
:Package = "MyLanguage.Natural",
:Keyword = :count,
:Function = func {
if not isattribute(self,:count_times) {
AddAttribute(self,:count_times)
Count_Times = 0
}
if Expr(1) > Expr(2) {
nStep = -1
else
nStep = 1
}
if Count_Times = 0 {
see nl+"The Numbers!" + nl
Count_Times++
else
see nl + "I will count Again!" +nl
}
for x = Expr(1) to Expr(2) step nStep {
see nl+x+nl
}
CommandReturn(fabs(Expr(1)-Expr(2))+1)
}
])
46.2 Defining Commands
To define new command we can use the DefineNaturalCommand object
This object provides the next methods :-
• SyntaxIsKeyword(aPara)
• SyntaxIsKeywordNumber(aPara)
• SyntaxIsKeywordNumberNumber(aPara)
• SyntaxIsKeywordNumbers(aPara,nCount)
• SyntaxIsKeywordString(aPara)
• SyntaxIsKeywordStringString(aPara)
46.2. Defining Commands 346
3. Ring Documentation, Release 1.5.1
• SyntaxIsKeywordStrings(aPara,nCount)
• SyntaxIsKeywordExpression(aPara)
• SyntaxIsKeywordExpressionExpression(aPara)
• SyntaxIsKeywordExpressions(aPara,nCount)
• SyntaxIsCommand(aPara)
• SyntaxIsCommandNumber(aPara)
• SyntaxIsCommandNumberNumber(aPara)
• SyntaxIsCommandNumbers(aPara,nCount)
• SyntaxIsCommandString(aPara)
• SyntaxIsCommandStringString(aPara)
• SyntaxIsCommandStrings(aPara,nCount)
• SyntaxIsCommandExpression(aPara)
• SyntaxIsCommandExpressionExpression(aPara)
• SyntaxIsCommandExpressions(aPara,nCount)
File: mylanguage.ring
load "stdlib.ring"
load "naturallib.ring"
MyLanguage = New NaturalLanguage {
SetLanguageName(:MyLanguage)
setCommandsPath(CurrentDir()+"/../command")
SetPackageName("MyLanguage.Natural")
UseCommand(:Hello)
UseCommand(:Count)
UseCommand(:Print)
UseCommand(:IWantWindow)
UseCommand(:WindowTitleIs)
UseCommand(:IWantButton)
}
Example (1)
In the next example we will define the Print command.
We will use the SyntaxIsKeywordExpression() Method.
We pass list (as Hash) to the method. We determine the package name, the keyword and the function that will be
executed.
Inside this function we uses the Expr(nExprNumber) function to get the expression value that the user will write after
the keyword.
File: print.ring
DefineNaturalCommand.SyntaxIsKeywordExpression([
:Package = "MyLanguage.Natural",
:Keyword = :print,
:Function = func {
See Expr(1)
}
])
46.2. Defining Commands 347
4. Ring Documentation, Release 1.5.1
Usage:
load "mylanguage.ring"
MyLanguage.RunString('
print "Hello, World!"
')
Output:
Hello, World!
Example (2)
File: iwantwindow.ring
DefineNaturalCommand.SyntaxIsCommand([
:Package = "MyLanguage.Natural",
:Command = "i want window",
:Function = func {
See "Command: I want window" + nl
}
])
Usage:
load "mylanguage.ring"
MyLanguage.RunString('
i want window
')
Output:
Command: I want window
Example (3)
File: windowtitleis.ring
DefineNaturalCommand.SyntaxIsCommandString([
:Package = "MyLanguage.Natural",
:Command = "window title is",
:Function = func {
See "Command: Window title is " + Expr(1) + nl
}
])
Usage:
load "mylanguage.ring"
MyLanguage.RunString('
I want window and the window title is "Hello World"
')
Output:
Command: I want window
Command: Window title is Hello World
46.2. Defining Commands 348
5. Ring Documentation, Release 1.5.1
46.3 Natural Library - Operators
In the next example we uses the Count command without using operators
load "mylanguage.ring"
MyLanguage.RunString("
Hello
Count 1 5
Count 5 1
")
We can add more description
load "mylanguage.ring"
MyLanguage.RunString("
Hello, Please Count from 1 to 5 then count from 5 to 1
")
Also we can use operators like “(” and ”)” around the instruction
load "mylanguage.ring"
MyLanguage {
SetOperators("()")
RunString("
Here we will play and will try something
that looks like Lisp Syntax
(count (count 1 5) (count 20 15))
Just for fun!
")
}
46.4 Defining commands using classes
This section is related to the implementation details.
When we define new command, Each command is defined by the Natural Library as a class.
We have the choice to define commands using the simple interface provided by the DefineNaturalCommand object or
by defining new class as in the next examples.
If we used DefineNaturalCommand (More Simple), The class will be defined during the runtime.
File: hello.ring
Package MyLanguage.Natural
class Hello
func AddAttributes_Hello
AddAttribute(self,:hello)
func GetHello
See "Hello, Sir!" + nl + nl
File: count.ring
46.3. Natural Library - Operators 349
6. Ring Documentation, Release 1.5.1
Package MyLanguage.Natural
class Count
func Getcount
StartCommand()
CommandData()[:name] = :Count
CommandData()[:nExpr] = 0
CommandData()[:aExpr] = []
func BraceExprEval_Count nValue
if isCommand() and CommandData()[:name] = :Count {
if isNumber(nValue) {
CommandData()[:nExpr]++
CommandData()[:aExpr] + nValue
if CommandData()[:nExpr] = 2 {
Count_Execute()
}
}
}
func AddAttributes_Count
AddAttribute(self,:count)
func Count_Execute
if not isattribute(self,:count_times) {
AddAttribute(self,:count_times)
Count_Times = 0
}
if Expr(1) > Expr(2) {
nStep = -1
else
nStep = 1
}
if Count_Times = 0 {
see nl+"The Numbers!" + nl
Count_Times++
else
see nl + "I will count Again!" +nl
}
for x = Expr(1) to Expr(2) step nStep {
see nl+x+nl
}
CommandReturn(fabs(Expr(1)-Expr(2))+1)
46.4. Defining commands using classes 350
7. CHAPTER
FORTYSEVEN
WEB DEVELOPMENT (CGI LIBRARY)
In this chapter we will learn about developing Web applications using a CGI Library written in the Ring language.
47.1 Configure the Apache web server
We can use Ring with any web server that support CGI. In this section we will learn about using Ring with the Apache
HTTP Server.
You can download Apache from : http://httpd.apache.org/
Or you can get it included with other projects like
XAMPP : https://www.apachefriends.org/download.html
Install then open the file:
xamppapacheconfhttpd.conf
search for
<Directory />
Then after it add
Options FollowSymLinks +ExecCGI
So we have
<Directory />
Options FollowSymLinks +ExecCGI
Search for the next line and be sure that it’s not commented
LoadModule cgi_module modules/mod_cgi.so
Search for : AddHandler cgi-script
Then add ”.ring” to the supported cgi extensions
Example
AddHandler cgi-script .cgi .ring
Example
AddHandler cgi-script .cgi .pl .asp .ring
351
8. Ring Documentation, Release 1.5.1
Run/Start the server
Create your web applications in a directory supported by the web server.
Example:
Apache2.2htdocsmywebapplicationfolder
Example:
xampphtdocsmywebapplicationfolder
Inside the source code file (*.ring), Add this line
#!c:ringbinring.exe -cgi
Note: Change the previous line based on the path to ring.exe in your machine
47.2 Ring CGI Hello World Program
The next program is the Hello World program
#!c:ringbinring.exe -cgi
See "content-type : text/html" +nl+nl+
"Hello World!" + nl
47.3 Hello World Program using the Web Library
We can use the web library to write CGI Web applications quickly
Example (1) :
#!c:ringbinring.exe -cgi
Load "weblib.ring"
Import System.Web
New Page
{
Text("Hello World!")
}
Example (2) :
#!c:ringbinring.exe -cgi
Load "weblib.ring"
Import System.Web
WebPage()
{
Text("Hello World!")
}
47.2. Ring CGI Hello World Program 352
9. Ring Documentation, Release 1.5.1
Tip: the difference between ex. 1 and ex. 2 is using WebPage() function to return the page object instead of creating
the object using new statement.
47.4 Web Library Features
The next features are provided by the Web library to quickly create web applications.
• Generate HTML pages using functions
• Generate HTML pages using objects
• HTTP Get
• HTTP Post
• Files Upload
• URL Encode
• Templates
• CRUD MVC Sample
• Users Logic & Registration Sample
47.5 HTTP Get Example
The Page User Interface
#!c:ringbinring.exe -cgi
Load "weblib.ring"
Import System.Web
New Page
{
Title = "Test HTTP Get"
divstart([ :style = StyleSizeFull() ] )
boxstart()
text( "Test HTTP GET" )
newline()
boxend()
divstart([ :style = Styledivcenter("600px","550px") +
StyleGradient(21) ])
divstart([:style = stylefloatleft() + stylesize("100px","100%") +
stylecolor("black") + stylegradient(58)])
formstart("ex5.ring")
tablestart([ :style = stylesize("65%","90%") +
stylemarginleft("35%") +
stylemargintop("30%") ])
rowstart([])
cellstart([])
text ( "Name : " )
cellend()
cellstart([])
cTextboxStyle = StyleMarginLeft("5%") +
StyleWidth("250px") +
StyleColor("black") +
47.4. Web Library Features 353