OSDN Git Service

4fa2f8ee9607c07ddf98333bee2ad34b80aae6eb
[ring-lang-081/ring.git] / docs / en / target / faq.txt
1 .. index:: 
2         single: Frequently Asked Questions; Introduction
3
4 ================================
5 Frequently Asked Questions (FAQ)
6 ================================
7
8
9 .. index:: 
10         pair: Frequently Asked Questions; Why do we need Yet Another Programming Language (YAPL)?
11
12 Why do we need Yet Another Programming Language (YAPL)?
13 =======================================================
14
15 The language comes with better support for natural language programming and declarative
16 programming. The innovation comes in supporting these paradigms with new practical techniques
17 on the top of object-oriented programming and functional programming. Ring provides the programmers
18 with the tools required to build a natural language like Supernova or a declarative language
19 like REBOL and QML without the need to know anything about (compilers and parsing). You get
20 the language constructs ready for use to create domain-specific languages in a fraction of time.
21
22 Take a look at the Supernova programming language, in this language you can type: 
23 (I want window and the window title is hello world.) and it will create a GUI window 
24 with "Hello, World!" as the window title. When I created Supernova language in 2010, i discovered
25 that using the natural code can be (similar to English and without limits and we can use the power
26 of human language in programming) but to implement that you need a new language that has: 
27
28 (1) General Purpose 
29
30 (2) Practical 
31
32 (3) Can create natural languages very quickly. 
33
34 So we can get a system that can increase ease of use and productivity to the maximum level. 
35
36 So I created Ring because it was the best way to achieve this goal.
37
38 Supernova was just a test of the idea, it helped getting a better view of the advantages and
39 the disadvantages of the idea. And After testing the new ideas you are provided with something
40 practical. So now we have Ring after Supernova. A story that is maybe similar to having Python 
41 after ABC.Where Python avoids the problems of ABC, but keeps the advantages of ABC. Also, Ring
42 learns from Ruby and ROR's story. The language power could appear in frameworks better than the
43 direct usage as a general purpose language. Also Ring comes with a clear goal/motivation; 
44 (Creating a new version of the PWCT Software) something that was learned from the design the 
45 C language in a certain way to create the Unix Operating System. In other words, you have a 
46 goal that directs you in each design decision.
47
48 You will understand the value of our decisions once you start trying to solve the problem
49 that we will use Ring to solve. The questions is: could you enable any one in the world 
50 without knowledge about computer programming concepts to create very powerful software?
51 Scientifically the answer is (visual Programming) and (natural Programming). 
52 In practice we are still away from switching to these paradigms without introducing 
53 other problems. Ring is designed to solve this problem.
54 It is designed to provide natural programming in a practical way. And to create a powerful 
55 visual programming tool. Ring is designed to be a new world of programming after 10 years 
56 of research in visual programming and natural languages.
57
58 The Ring Programming Language (Compiler+VM) is developed 100% using visual programming without
59 writing a single line of code. I used my tool (Programming Without Coding Technology) to design
60 everything and get the C code generated for me. 
61
62 Advantages ? 
63
64 (1) Faster 
65
66 (2) No Syntax Errors 
67
68 (3) Easy to understand and manage the code because the abstraction level is higher
69
70 (4) No critical disadvantages because you can control everything as writing your code.
71
72 Using my experience in using visual programming for 10 years and natural programming for 5 years,
73 I designed Ring to move the knowledge to mainstream programmers by providing a practical language 
74 that supports these ideas.
75
76
77 I agree that each programmer/developer has the freedom to form his opinions about any software
78 including programming languages. Ring is not an exception but you may miss the idea behind the 
79 language. It is innovative and may help you to think differently about how to solve your problems.
80 Maybe this is not clear to many programmers because It is a practical language and includes many
81 features known to programmers and when a programmer looks at the language they maight think that 
82 nothing new because it's familiar. I created Ring to solve problems in a different way. Where I
83 will start programming just by describing the software using new natural interfaces that I will
84 implement later when I move from the design stage to the implementation stage. 
85 (I don't determine the time to switch between stages, You are free to use Agile methods). 
86 Since Ring is a new language you have 3 options:
87
88 (1) To not care at all for now.
89
90 (2) Think of the future of the language and help us if you understand the idea and want to contribute.
91
92 (3) Wait and come back again in the future to use it. 
93
94 Summary:
95
96 * Ring is designed based on a need to develop a new version of the PWCT software. 
97 Once we finish PWCT 2.0 we will have good and large software developed using Ring.
98
99 * We will push declarative and natural paradigms many steps forward. Also in next versions 
100 we have a plan to present a new paradigm for network programming and concurrency. We tested this
101 new paradigm through simple prototypes during the last years and we will integrate it with Ring 
102 in future releases.
103
104 .. index:: 
105         pair: Frequently Asked Questions; Why is Ring weakly typed?
106
107 Why is Ring weakly typed?
108 =========================
109
110 Because it's faster and more natural, and this is important for the language's goals. One
111 of the rules is: the data type at the beginning affects the final result. 
112 For example, when you type "Print : " + 5 , The String comes first, so 5
113 will be converted to a String. While when you type 5 + "10" The number comes first so "10"
114 will be converted to 10. This helps a lot to quickly convert between numbers and strings using
115 the same operator. If you want to prevent conversion (Write code that prevent conversion) In
116 these cases you will notice that what you are writing is less code (And can be removed). 
117
118 Weakly typed = automatic conversion and *automatic* is *good thing* and is better than *manual*
119 if you know how to use it correctly.
120
121
122 .. index:: 
123         pair: Frequently Asked Questions; What are the advantages to using Ring over Lisp or Smalltalk?
124
125 What are the advantages to using Ring over Lisp or Smalltalk?
126 ====================================================================
127
128 Smalltalk and Lisp are GREAT languages. I like many of the concepts behind them but I'm sure
129 that selecting the right programming language is based on the problem and comes after the problem's
130 definition. I have a problem that I want to solve and these GREAT languages are not ideal for 
131 this problem so I designed Ring.
132
133 When you design a new language, You can learn from the past but you must look forward and live
134 in the future. What you know about natural programming maybe based on the *old knowledge* about
135 the power of these paradigms in the practical world and I agree with you but I see other
136 techniques that can be applied to get this to work in practice. What you miss about
137 *natural language* is that they are *context sensitive* and this means we can use it and think
138 differently about how we can express our ideas. 
139
140 Example : I want window contains 3 buttons. 
141
142 In one sentence I created 4 objects (The window and the three buttons) and added the buttons
143 to the window. The idea of natural programming is to get many things done like that.
144
145 .. index:: 
146         pair: Frequently Asked Questions; Why is Ring largely focussed on UI creation?
147
148 Why is Ring largely focussed on UI creation?
149 ============================================
150
151 Yes UI creation is one of the important things in the language features because it is designed
152 to create a visual programming tool, But the language is a multi-paradigm language where we can
153 select the programming paradigm based on the problem.
154
155
156 .. index:: 
157         pair: Frequently Asked Questions; Is Ring some sort of an improvement of PHP?
158
159 Is Ring some sort of an improvement of PHP?
160 ==========================================
161
162 Ring is not designed to replace PHP, Lua or Smalltalk. Ring's support for declarative
163 programming and natural language programming is very innovative and much better than staying 
164 with procedural, object-oriented and functional languages. Ring see the future in programming
165 without code (using natural languages) and is designed to support that.
166
167 .. index:: 
168         pair: Frequently Asked Questions; What are the advantages of using Ring over native C or C++?
169
170 What are the advantages of using Ring over native C or C++?
171 ===========================================================
172
173 Ring provides a better way to mix between different programming paradigms in solving problems.
174
175 The different programming paradigms play well together in the same language. 
176
177 (1) It's easy to switch from one programming paradigm to another one because the language constructs use similar syntax for similar concepts.
178
179 (2) The paradigms are provided to interact and used together in different layers in the software. 
180
181 for example you can create a game engine using object-oriented programming but write the game code using declarative programming or natural programming and behind the scenes your declarative or natural code will use the object-oriented classes.
182
183 (3) Ring is more productive and natural than C/C++.
184
185 (4) Ring is a dynamic language. We can generate and execute code during the runtime. Ring is dynamically typed and weakly typed for flexibility.
186
187 (5) The Garbage collector is generational (escape analysis) and also uses reference counting. it's very fast and still provides control to the programmer who can delete memory at any time.
188
189 (6) Ring's compiler and virtual machine are just 20,000 lines of ANSI C code that can be compiled and used in any platform.
190
191 (7) You can use C/C++ libraries and Ring comes with code generator to create wrappers from C functions or C++ classes. so when you need more performance or when you need to use more libraries you can easily do that.
192
193
194 .. index:: 
195         pair: Frequently Asked Questions; What is the difference between Ring and Python? And is Ring Open Source?
196
197 What is the difference between Ring and Python? And is Ring Open Source?
198 ========================================================================
199
200 Yes the language is Open Source (MIT license)
201
202 In general I like Python and Ruby but I was looking for a language more suitable for creating the next version of
203 the Programming Without Coding Technology (PWCT) software so I started the Ring design.
204
205 Some simple changes that matters for my goal are 
206
207 (1) Not case sensitive
208
209 (2) The list index start from 1
210
211 (3) You can call functions before definition
212
213 (4) Don't use Python syntax like (indentation, using self, :, pass & _) 
214
215 (5) Weakly typed (convert automatically between types based on context)
216
217 (6) The programs follow simple and constant structure (Statements then functions then packages and classes)
218
219 (7) Using the '=' operator for assignment and for testing values
220
221 Critical changes are
222
223 (1) Small Language : The Ring compiler + Virtual Machine = 15K lines of C code , the other 500K lines are related to libraries and are optional when we go for using the language in C/C++ programs.
224
225 (2) The Garbage collector : Uses Escape Analysis/Reference counting and give the programmer the ability to determine when to delete memory using the assignment operator
226
227 (3) Compact Syntax : Ring is not line sensitive, you don't need to write ; or press ENTER to separate between statements
228
229 (4) Using { } to access the object then using the object attributes and methods directly
230
231 (5) Natural Programming : It's very easy to create natural interfaces using Ring based on OOP
232
233 (6) Declarative Programming using Nested Structure
234
235 The Ring programming language is designed based on my experience from using many other
236 languages like C, C++, C#, Lua, PHP, Python, Ruby, Harbour, Basic and Supernova
237 And the language comes with innovative features added to achieve the language goal
238
239 * Applications programming language.
240 * Productivity and developing high quality solutions that can scale.
241 * Small and fast language that can be embedded in C/C++ projects.
242 * Simple language that can be used in education and introducing Compiler/VM concepts.
243 * General-Purpose language that can be used for creating domain-specific libraries, frameworks and tools.
244 * Practical language designed for creating the next version of the Programming Without Coding Technology software.
245
246 .. index:: 
247         pair: Frequently Asked Questions; What are the advantages to using Ring over Python and Ruby?
248
249 What are the advantages to using Ring over Perl, PHP, Python or Ruby?
250 =====================================================================
251
252 (1) Ring is New and Innovative. The language will let you think different about programming.
253
254 (2) Ring is Smaller. (Lessons learned from the Lua language)
255
256 (3) Ring is Simple. (Lessons learned from the BASIC and Clipper/Harbour languages)
257
258 (4) Ring is more Natural. (Lessons learned from the Supernova language)
259
260 (5) Ring is more Declarative. (Lessons learned from REBOL and QML languages)
261
262 (6) Ring Implementation is Transparent, Visual and comes with Rich Features.
263
264
265 .. index:: 
266         pair: Frequently Asked Questions; What are the advantages to using Ring over Tcl and Lua?
267
268 What are the advantages to using Ring over Tcl or Lua?
269 ======================================================
270
271 (1) Clean Code (More Natural)
272
273 (2) More Features (A lot of useful programming paradigms)
274
275 .. index:: 
276         pair: Frequently Asked Questions; What are the advantages to using Ring over C# or Java?
277
278 What are the advantages to using Ring over C# or Java?
279 ======================================================
280
281 (1) Compact Code (Clean and Natural), More Productivity and Flexibility.
282
283 (2) Better support for Declarative Programming and Natural Programming
284
285
286 .. index:: 
287         pair: Frequently Asked Questions; The documentation says functional programming is supported, but then this happens?
288
289
290 The documentation says functional programming is supported, but then this happens?
291 ==================================================================================
292
293 The question was about this code
294
295 .. code-block:: ring
296
297         f = func {
298             a = 42
299             return func { return a }
300         }
301  
302         innerF = call f()
303         call innerF()
304
305 Output:
306
307 .. code-block:: none
308
309         Using uninitialized variable : a In function _ring_anonymous_func_16601()
310
311 The Answer:
312
313 * It's Anonymous Functions, i.e. Not Closures.
314
315 * Many developers asked about supporting Closures and during language development we may add new features that doesn't go against the language goals or spirit.
316
317 * You can use classes and objects when you want to merge between the state and functions to provide a clear solution.
318
319 * You can use Lists and put the anonymous function inside the List then return the list that contains the state and the function. Pass the list to the function when you use it.
320
321 * You can use eval() and substr() to add the variable value directly to the anonymous function before return.
322
323 * We protect you from other scopes when you define the function. In Ring we provided the Three Scopes Rule where at each point you have only at maximum three scopes (Global, Object Scope and Local Scope).
324
325 * We don't get everything from everywhere to be like others! We don't need to do that. If we will think like that then we will create a very complex language or we will save our time and use other languages.
326
327 * When you think about learning or studying a new language concentrate about (What is new?) and (What is better in this language?) to know when to use it. Don't compare a new language just released little months ago with languages started many years ago and expect to find everything that you used to have.
328
329 * Each programming language miss features in other languages. The idea is not the Features. it's the spirit and ability behind all of the features together.
330
331
332
333 .. index:: 
334         pair: Frequently Asked Questions; Why the ability to define your own languages Instead of just handing over the syntax so you can parse it using whatever code you like?
335
336 Why the ability to define your own languages Instead of just handing over the syntax so you can parse it using whatever code you like?
337 ======================================================================================================================================
338
339 It's innovation - You create natural statements without the need to learn about parsing. 
340 You just use Classes which is intelligent decision (where later we can mix between classes to
341 support more statements based on the context - We can change and translate the defined 
342 statements and many more!). Also the statements are added in Ring World where you can use
343 any Ring statement.
344
345 .. index:: 
346         pair: Frequently Asked Questions; Why you can specify the number of loops you want to break out of?
347
348 Why you can specify the number of loops you want to break out of?
349 =================================================================
350
351 The language supports programming in the small and programming in the large. The selection
352 of what features to use is based on what are you going to do. Any programmer can write 
353 poorly code in any language if he/she wants to do that. The idea is what must be done in 
354 the language design to prevent errors without causing other problems like killing flexibility.
355
356 Read some source code in the Linux Kernel and Ruby Implementation for example, You will find good
357 usage for GOTO as a practical example that General Rules are not for All Use Cases and great
358 programmers know when to break the rules. I'm not saying go and use GOTO or saying Ring add
359 things like that. But the ability to break more than one loop and/or the ability to break the
360 loop from sub functions is practical for small programs.
361
362 Anyway these are some of the small new things added by the language (Not the big idea).
363
364 .. index:: 
365         pair: Frequently Asked Questions; Why Ring uses 'See', 'Give', 'But' and 'Ok' Keywords?
366
367 Why Ring uses 'See', 'Give', 'But' and 'Ok' Keywords?
368 =====================================================
369
370 See and Give are selected not to be "opposite actions" but to reflect what I want to do as a programmer.
371
372 When I want to see something on the screen I use 'See'.
373
374 When I want to give some input to the program I use 'Give'.
375
376 My selection of "but" and "ok" is based on selecting keywords that can be written quickly.
377
378 Also using "but" is easy to remember than elseif/elif/elsif where each language select a different keyword.
379
380 In Ring 1.1 and later versions All of this is just an option.
381
382 You can use 'Put' and 'Get' instead of 'See' and 'Give'
383
384 You can use 'elseif' and 'end' insetad of 'But' and 'Ok'
385
386 It's your choice. In Ring we have syntax flexibility where we provide more than one style.
387
388 Also you can change the language keywords and operators.
389
390 Also you can define new natural languages too.
391
392 .. index:: 
393         pair: Frequently Asked Questions; Philosophy behind data types in Ring
394
395 What is the philosophy behind data types in Ring?
396 =================================================
397
398 The Ring programming language is designed to be SMALL. 
399 The language provides the basic constructs that you need to do anything!
400 One of the goals is to keep the basic constructs simple and small as possible.
401
402 Using Lists in Ring you can
403
404 * Create Arrays (one data type)
405 * Create Lists (Mix of data types)
406 * Create Tree (Nested arrays)
407 * Use String Index (Looks like Dictionary/Hash Table)
408
409 The same principle is applied to Numbers
410
411 * You can use the number for int value
412 * You can use the number for double value
413 * You can use the number for Boolean value (True/False)
414
415 The sample principle is applied for Strings
416
417 * You can use the string for storing one character 
418 * You can use the string for storing text (one or many lines)
419 * You can use the string for storing binary data
420 * You can use the string for storing date
421 * You can use the string for storing time
422 * You can use the string for storing NULL values (empty strings)
423
424 And we have Object Oriented Support + Operator Overloading where the programmer
425 can define new data types and use them as default types defined by the language
426
427 So We have
428
429 * A small and simple language that someone can pick in little days
430 * A fast language that provide primitive types (String - Number - List - Object)
431 * A flexible language that can be extended using OOP to add new types according to the application domain
432
433
434 .. index:: 
435         pair: Frequently Asked Questions; What about the Boolean values in Ring?
436
437 What about the Boolean values in Ring?
438 ======================================
439
440
441 You can use true for 1 and false for 0
442
443 when you test the result of Boolean expressions in your code.
444
445 Just when you print the value using the see command you will see 1 for (true) and 0 for (false)
446
447 Why ?
448
449 Because Ring contains only 4 types of variables
450
451 (1) Number
452
453 (2) String
454
455 (3) List
456
457 (4) Object
458
459 The first type (Number) is used to represent int, double and Boolean values.
460
461 The second type (String) is used to represent char, array of characters, date and time.
462
463 The third type (List) is used to represent Arrays of one type, Arrays of more than one type, Hash (Dictionary), Tree, etc.
464
465 The object can be an object created from a Ring class (Any Class) or just a C Pointer that we get from calling a C/C++ function/method.
466
467 Why ?
468
469 The Ring is designed to give the programmer/developer the most simple constructs that can be used to do everything.
470 The programmer/developer can customize the language by creating new classes (and use operator overloading) to get more types that he care about according to the problem domain.
471
472 Why ?
473
474 Because simple is better, and easy to learn and remember!
475 And this provide flexibility to convert between high level types that can be represented using the same basic type
476
477
478 .. index:: 
479         pair: Frequently Asked Questions; Goal of including the "Main" function in Ring
480
481 What is the goal of including the "Main" function in Ring?
482 ==========================================================
483
484 The main function is very important, you need it when you want to write statements that uses 
485 local variables instead of the Global scope.
486
487 Example:
488
489 .. code-block:: ring
490
491         x = 10
492         myfunc()
493         See "X value = " + X  # here I expect that x will be (10)
494                               # but I will get another value (6) because myfunc() uses x !
495         Func myfunc
496            for x = 1 to 5
497                See x + nl
498            next
499
500 Output:
501
502 .. code-block:: ring
503
504         1
505         2
506         3
507         4
508         5
509         X value = 6
510
511 Now using the Main function
512
513 .. code-block:: ring
514
515         Func Main 
516            x = 10
517            myfunc()
518            See "X value = " + X                         
519
520         Func myfunc
521            for x = 1 to 5
522                See x + nl
523            next
524
525 Output
526
527 .. code-block:: ring
528
529         1
530         2
531         3
532         4
533         5
534         X value = 10
535
536 .. index:: 
537         pair: Frequently Asked Questions; List index start from 1
538
539 Why the list index start from 1 in Ring?
540 ========================================
541
542 It\'s about how we count in the real world, when we have three apples in our hand
543
544 we say 1 2 3 
545
546 We don\'t start from 0
547
548 The question must be why the other languages start from 0 ?
549
550 The answer is, because this is related to the machine and how we deal with values and memory address.
551
552 Example
553
554 we have array called myarray[5]
555
556 In memory : myarray will have an address
557
558 The first item will be stored in that address
559
560 The second item will come after that address and so on
561
562 Now when we need to point to the first item we need the address of myarray
563
564 So we type myarray[0] because myarray + 0 result will still point to the first item
565
566 for the second item myarray[1] because myarray + 1 result will point to the second item and so on
567
568 In Low Level languages or languages near to the machine it\'s good to be like this
569
570 But for high level language designed for applications it\'s better to be natural
571
572 Example
573
574 .. code-block:: ring
575
576         mylist = [1,2,3,4,5]
577         for x = 1 to len(mylist)
578                 see x + nl
579         next
580
581 In the previous example we start from 1 to the length of the array
582 if the index starts from 0 we will write
583
584 .. code-block:: ring
585
586         for x = 0 to len(mylist)-1
587
588 or remember the for loop in other languages
589
590 .. code-block:: ring
591
592         for(x=0 ; x<nMax ; x++ )
593
594 You will use the < operator !
595
596
597 .. index:: 
598         pair: Frequently Asked Questions; Why Ring is not case-sensitive
599
600 Why Ring is not case-sensitive?
601 ===============================
602
603 (1) To be more human-friendly
604
605 (2) Like Ada, SQL, Pascal, Delphi, Visual Basic, Visual FoxPro, etc. 
606
607 (3) To help in supporting Natural Language Programming.
608
609 (4) To be able to select your favorite style when writing the language keywords
610
611 .. code-block:: ring
612
613         see "lower case!"
614
615 .. code-block:: ring
616
617         SEE "UPPER case!"
618
619 .. code-block:: ring
620
621         See "First Letter is UPPER case!"
622
623 (5) To avoid getting error message when writing quick tests then type "variable" instead of "Variable".
624
625 (6) To avoid getting error message when you type "Dosomething()" instead of "doSomething()"
626
627 (7) In Ring, No conflict between Variables, Method Names & Classes Names
628
629 We can write person as variable name and Person as class name.
630
631 .. code-block:: ring
632         
633         person = new Person     
634         class Person 
635                 name address phone
636         
637
638 .. index:: 
639         pair: Frequently Asked Questions; Why the Assignment operator uses Deep copy?
640
641 Why the Assignment operator uses Deep Copy?
642 ===========================================
643
644 "Because it's a poor tradeoff to add complexity for dubious performance gains, a good
645 approach to deep vs. shallow copies is to prefer deep copies until proven otherwise."
646         , Steve McConnell, Code Complete 
647
648 (1) It's more natural, When you use the assignment operator, You expect a deep copy.
649
650 (2) If you don't need a deep copy, Just don't use it! 
651
652 (3) The Ring language is designed to reduce references usage as much as possible.
653
654 (4) The Ring language is designed to make using references simple and possible in special cases where this make sense.
655
656 (5) We have references when this is natural, like passing lists and objects to functions,
657         creating objects (Like GUI Objects) from a C/C++ library, returning an object stored 
658         inside a list.
659
660 (6) It is a feature, We can use it to create pure functions. The Value() function in the
661         stdlib uses this feature to pass lists & objects by value when we need this.
662
663 (7) When we need references, It's recommended to create a class that manage sharing lists and objects.
664         
665 (8) It's more safe at the application level to avoid many logical errors.
666
667 (9) In Ring, we start without thinking about the little details and concentrate on the application, You
668         don't have to write the type (Dynamic Typing), You don't have to write explicit
669         conversions between numbers and strings (Weakly Typed) and you don't have to select
670         between using values or references, You don't have to write the scope (Lexical Scoping).
671
672 (10) In Ring, we have smart garbage collector (Simple & Fast), We can delete the memory directly
673         at any time using the Assignment operator too. Reducing references usage or using them through
674         managers helps a lot to achieve this goal. by doing this we have full control.
675
676 (11) If you want to create references and avoid creating a manager, 
677         You can use Object2Pointer() and Pointer2Object() functions
678         But It's not the Ring way "Spirit" to do things.
679
680 .. index:: 
681         pair: Frequently Asked Questions; Constructor methods in Ring
682
683
684 Is there constructor methods in Ring?
685 =====================================
686
687 When you create new object for example
688
689 .. code-block:: ring
690
691         new point
692
693 1 - Ring will allocate dynamic memory space to be used for the new object attributes that Ring doesn't know anything about them.
694
695 2 - Ring will change the current local scope and the current object scope to use the object state created in step (1)
696
697 3 - Ring will move the execution to the class Region (After the class name and before any methods)
698
699 4 - Any Instructions/Code in the class region will be executed as any Ring code
700
701 5 - Control is moved from the class region to the location of (new point) once we reach the end of the class region or we uses a Return command.
702
703 So All attributes that added to the object are dynamic attributes, this mean that you can control what attributes will be added through the runtime.
704
705 Example:
706
707 .. code-block:: ring
708
709         $3D = False
710         see  new point 
711         $3D = True
712         see new point 
713
714         class point
715                 x y
716                 if not $3D return ok
717                 z
718
719 Output:
720
721 .. code-block:: none
722
723         x: NULL
724         y: NULL
725         x: NULL
726         y: NULL
727         z: NULL
728
729 You have an option to call init() method directly when you create a new object 
730
731 This method can do anything with the object attributes as it will be called after creating the object and executing the class region code.
732
733
734 .. code-block:: ring
735
736         p1 = new point3d(100,200,300)
737         see p1
738
739         class point3d
740                 x y z
741                 func init p1,p2,p3
742                         x=p1 y=p2 z=p3
743
744
745 .. index:: 
746         pair: Frequently Asked Questions; What happens when we create a new object?
747
748 What happens when we create a new object?
749 =========================================
750
751 1- When you create an object, the class region code will be executed and you will have the object attributes based on the code in that region
752
753 2- Ring don't care about the object methods until you start calling a method
754
755 3- When you call a method, Ring will check the object class and the class parent (if you are using inheritance) and will collect the methods for you to be used now or later from any object that belong to the same class.
756
757 4- Since methods are dynamic and each object get the method from the class, you can after creating objects, add new methods and use it with the object or any object created or will be created from the same class.
758
759 Example:
760
761 .. code-block:: ring
762
763         o1 = new point {x=10 y=20 z=30}
764         o2 = new point {x=100 y=200 z =300}
765
766         addmethod(o1,"print", func { see x + nl + y + nl + z + nl } )
767
768         o1.print()
769         o2.print()
770
771         class point x y z
772
773 Output:
774
775 .. code-block:: none
776
777         10
778         20
779         30
780         100
781         200
782         300
783
784 .. index:: 
785         pair: Frequently Asked Questions; Getter and Setter Methods
786
787 Can we use the attributes by accessing the Getter and Setter methods?
788 =====================================================================
789
790 Yes we can, The setter/getter methods are called automatically when you start using the attributes from outside the class
791 Also you can call the methods instead of using the attributes. It's your choice.
792
793 Example:
794
795 .. code-block:: ring
796
797         o1 = new Developer
798         o1.name = "Mahmoud"  see o1.name + nl
799         o1 { name = "Gal"  see name }
800         o1 { name = "Bert"  see name }
801
802         o1.setname("Marino")
803         see o1.getname()
804
805         Class Developer
806
807                         name language = "Ring Programming Language"
808
809                         func setname value
810                                         see "Message from SetName() Function!" + nl
811                                         name = value + " - " + language
812
813                         func getname
814                                         see "Message from GetName() Function!" + nl + nl
815                                         return "Mr. " + name + nl
816
817 Output
818
819 .. code-block:: none
820
821         Message from SetName() Function!
822         Message from GetName() Function!
823
824         Mr. Mahmoud - Ring Programming Language
825
826         Message from SetName() Function!
827         Message from GetName() Function!
828
829         Mr. Gal - Ring Programming Language
830         Message from SetName() Function!
831         Message from GetName() Function!
832
833         Mr. Bert - Ring Programming Language
834         Message from SetName() Function!
835         Message from GetName() Function!
836
837         Mr. Marino - Ring Programming Language
838
839 .. index:: 
840         pair: Frequently Asked Questions; Search of global names while defining the class attributes
841
842 Why should a search of global names be made while defining the class attributes?
843 ================================================================================
844
845 The question is why we don't avoid conflicts with global variable names when we
846 define the class attributes ?
847
848 At first remember that using the optional $ mark in the global variables names solve
849 the problem. Also using the Main function and avoiding global variables may help.
850
851 The Answer:
852
853 Ring is a dynamic language
854
855 We can in the run-time determine the class attributes (Add/Remove) 
856
857 We can execute (any code) while defining the class attributes
858
859 Example (1)
860
861 .. code-block:: ring
862
863         oPerson = new Person
864         Class Person
865            See "Welcome to the Ring language"
866
867 Example (2)
868
869 Customize attributes based on global variable value
870
871 .. code-block:: ring
872
873         $debug = true
874         oPerson = new Person
875         see oPerson
876         Class Person
877             if $debug  date=date()  time=time() ok
878
879 In the previous example when we have the $debug flag set to true, we will add the Date and Time
880 attributes to the object state.
881
882 Example (3)
883
884 Store the object index based on global variable
885
886 .. code-block:: ring
887
888         $ObjectsCount = 0
889         oPerson = new Person
890         see oPerson
891         oPerson2 = new Person
892         see oPerson2
893         Class Person
894               $ObjectsCount++
895               nIndex = $ObjectsCount
896
897 Output:
898
899 .. code-block:: ring
900
901         nindex: 1.000000
902         nindex: 2.000000
903
904 Common Example: 
905
906 * Connect to the database then get table columns (Using global Variable/Object).
907
908 * Create class attributes based on the column names.
909
910 * Later when you modify the database - you may don't need to modify your code.
911
912 It's flexibility but remember that power comes with great responsibility.
913
914
915 .. index:: 
916         pair: Frequently Asked Questions; Conflict between Global Variables and Class Attributes
917
918
919 Why Ring doesn't avoid the conflict between Global Variables and Class Attributes Names?
920 ========================================================================================
921
922 In this use case we have 
923
924 1 - Global Variable defined without a special mark like $
925
926 2 - Class contains Attributes defined using a special syntax (where we type the attribute name directly after the class)
927
928 3 - The Attributes are defined in the class region that allows writing code and using global variables
929
930 If I will accepted your proposal about changing how Ring find variables in the class region I must break one of the previous three features which will lead to more problems that are more important than this problem.
931
932 I don't like changing the feature number (1) because I would like to keep Ring code more clean and let the programmer decide when to use $ or not.
933
934 I don't like changing the feature number (2) because I like this feature and I don't like forcing the programmer to type
935 self.attribute 
936
937 I don't like changing the feature number (3) because it's very important in many applications to access global variables in the class region.
938
939 So what was my decision ? 
940
941 I decided to leave this case for the programmer who will decide what to do to avoid this special case
942
943 1 - The programmer can avoid using global variables (Better) and can use the Main function (Optional)
944
945 2 - The programmer can use $ before the variable name or any mark like global_ or g_
946
947 3 - The programmer can use self.attribute after the class name to define the attributes 
948
949 In general, for small programs you can use global variables and functions.
950 For large programs, use classes and objects and small number of global variables or avoid them at all.
951
952 .. index:: 
953         pair: Frequently Asked Questions; Where can I write a program and execute it?
954
955
956 Where can I write a program and execute it?
957 ===========================================
958
959 Run the Ring Notepad where you can write/execute programs.
960
961 If you want to run programs using the command line
962
963 Add Ring/bin folder to the path then
964
965 .. code-block:: none
966         ring <filename.ring>|<filename.ringo>
967
968 .. index:: 
969         pair: Frequently Asked Questions; How to get the file size using ftell() and fseek() functions?
970
971 How to get the file size using ftell() and fseek() functions?
972 =============================================================
973
974
975 The next function can be used to get the file size without reading the file!
976
977 .. code-block:: ring
978
979         func getFileSize fp
980                C_FILESTART = 0
981                C_FILEEND = 2
982                fseek(fp,0,C_FILEEND)
983                nFileSize = ftell(fp)
984                fseek(fp,0,C_FILESTART)
985                return nFileSize
986
987 .. note:: The previous function take the fp (file pointer) as parameter, We can get the fp from opening the file using fopen() function.
988
989 .. code-block:: ring
990
991         fp = fopen("filename","r")
992
993         see  "File Size : " + getFileSize(fp) + nl
994
995 Another solution (Read the file)
996
997 .. code-block:: ring
998
999         see len(read("filename"))
1000
1001
1002 .. index:: 
1003         pair: Frequently Asked Questions; How to get the current source file path?
1004
1005 How to get the current source file path?
1006 ========================================
1007
1008 We can use the next function to get the current source file path
1009 then we can add the path variable to the file name
1010
1011 .. code-block:: ring
1012
1013         cPath = CurrentPath()
1014         func currentpath
1015                 cFileName = filename()
1016                 for x = len(cFileName) to 1 step -1
1017                         if cFileName[x] = "/"
1018                                 return left(cFileName,x-1)
1019                         ok
1020                 next
1021                 return cFileName
1022
1023
1024 .. index:: 
1025         pair: Frequently Asked Questions; What about predefined parameters or optional parameters in functions?
1026
1027 What about predefined parameters or optional parameters in functions?
1028 =====================================================================
1029
1030 if you want to use predefined parameters or optional parameters
1031 Just accept a list that works like hash/dictionary
1032
1033 Example
1034
1035 .. code-block:: ring
1036
1037         sum([ :a = 1, :b = 2])
1038         sum([ :a = 1 ])
1039         sum([ :b = 2 ])
1040         func sum pList
1041                 if plist[:a] = NULL pList[:a] = 4 ok
1042                 if plist[:b] = NULL pList[:b] = 5 ok
1043                 see pList[:a] + pList[:b] + nl
1044
1045 Output
1046
1047 .. code-block:: none
1048
1049         3
1050         6
1051         6
1052
1053
1054 .. index:: 
1055         pair: Frequently Asked Questions; How to print keys or values only in List/Dictionary?
1056
1057 How to print keys or values only in List/Dictionary?
1058 ====================================================
1059
1060
1061 If you want to print keys only or values only just select the index of the item (one or two).
1062
1063 Example
1064
1065 .. code-block:: ring
1066
1067
1068         C_COUNTRY = 1
1069         C_CITY = 2
1070         mylist = [
1071                 :KSA = "Riyadh" ,
1072                 :Egypt = "Cairo"
1073         ]
1074
1075         for x in mylist
1076                 see x[C_COUNTRY] + nl
1077         next
1078
1079         for x in mylist
1080                 see x[C_CITY] + nl
1081         next
1082
1083 Output
1084
1085 .. code-block:: none
1086
1087         ksa
1088         egypt
1089         Riyadh
1090         Cairo
1091
1092 .. index:: 
1093         pair: Frequently Asked Questions; Why I get a strange result when printing nl with lists?
1094
1095 Why I get a strange result when printing nl with lists?
1096 =======================================================
1097
1098 In the next code
1099
1100 .. code-block:: ring
1101
1102         list = 1:5        # list = [1,2,3,4,5]
1103         see list + nl
1104
1105 New Line will be added to the list then the list will be printed, the default print of the lists 
1106 will print a newline at the end, You added new newline and You have now 2 newlines to be printed.
1107
1108 .. code-block:: ring    
1109
1110         See <Expr>
1111
1112 The see command just print the final result of the expression, the expression will be evaluated as it
1113
1114 .. code-block:: ring
1115
1116         nl = char(13) + char(10) # just a variable that you can change to anything !
1117
1118 The + is an operator
1119
1120 .. code-block:: none
1121
1122         string + string ---> new string
1123         string + number ---> new string
1124         number + number ---> new number
1125         number + string ---> new number
1126
1127 list + item ---> nothing new will be created but the item will be added to the same list
1128
1129 Exception
1130
1131 number + nl -> New String
1132
1133 This exception is added to easily print numbers then new line.
1134
1135 No need for this with printing lists because after printing the last item we already get a new line.
1136
1137 .. index:: 
1138         pair: Frequently Asked Questions; Could you explain the output of the StrCmp() function?
1139
1140 Could you explain the output of the StrCmp() function?
1141 ======================================================
1142
1143 At first remember that you can check strings using '=' operator directly.
1144
1145 .. code-block:: ring
1146
1147         see strcmp("hello","hello") + nl +
1148         strcmp("abc","bcd") + nl +
1149         strcmp("bcd","abc") + nl
1150
1151 if the two strings are the same then it returns 0
1152
1153 abc and bcd aren't the same. in the second line it returns -1 and in the third line it returns 1
1154
1155 In the second line we compare between "abc" and "bcd"
1156
1157 Not equal because the first letter in "abc" = "a" 
1158 and the first letter in "bcd" = "b"
1159
1160 So we have "a" != "b" and "a" < "b"
1161
1162 So we get output = -1
1163
1164 In the third line we have "bcd" and "abc"
1165
1166 the first letter in "bcd" is "b" and the first letter in "abc" is "a"
1167
1168 So we have "b" != "a" and "b" > "a"
1169
1170 So we get output = 1
1171
1172 .. note:: ASCII("a") = 97 and ASCII("b") = 98 So "a" < "b" because 97 < 98
1173
1174
1175 .. index:: 
1176         pair: Frequently Asked Questions; How to use many source code files in the project?
1177
1178 How to use many source code files in the project?
1179 =================================================
1180
1181 Example:
1182
1183 I have the next folder
1184
1185 .. code-block:: none
1186
1187         C:\LRing
1188
1189 Contains the next files
1190
1191 .. code-block:: none
1192
1193         C:\LRing\t1.ring
1194         C:\LRing\mylib.ring
1195         C:\LRing\libs\mylib2.ring
1196
1197 The file t1.ring contains the next code
1198
1199 .. code-block:: ring
1200
1201         load "mylib.ring"
1202         load "libs\mylib2.ring"
1203         myfunc()
1204         test()
1205
1206 The file mylib.ring contains the next code
1207
1208 .. code-block:: ring
1209
1210         func myfunc
1211                 see "message from myfunc"+nl
1212
1213 The file libs\mylib2.ring contains the next code
1214
1215 .. code-block:: ring
1216
1217         func test
1218                 see "message from test" + nl
1219
1220 from the folder C:\LRing
1221
1222 If Ring is not added to the path you can add it or use the next command
1223
1224 .. code-block:: none
1225
1226         set path=%path%;c:\ring\bin;
1227
1228 Where c:\ring is the Ring folder
1229
1230 Now run
1231
1232 .. code-block:: none
1233
1234         Ring t1.ring
1235
1236 Output
1237
1238 .. code-block:: none
1239
1240         message from myfunc
1241         message from test
1242
1243 .. index:: 
1244         pair: Frequently Asked Questions; Why this example use the GetChar() twice?
1245
1246 Why this example use the GetChar() twice?
1247 =========================================
1248
1249 The GetChar() function accept one character from the keyboard buffer
1250
1251 In this example
1252
1253
1254 .. code-block:: ring
1255
1256
1257         While True
1258                 See "
1259                         Main Menu
1260                         (1) Say Hello
1261                         (2) Exit
1262                 "
1263                 Option = GetChar()
1264                 GetChar() GetChar()  # End of line
1265                 # the previous two lines can be replaced with the next line
1266                 # Give Option
1267
1268                 if Option = 1
1269                         see "Enter your name : " give cName
1270                         see "Hello " + cName
1271                 else
1272                         bye
1273                 ok
1274         End
1275
1276 We uses GetChar() Three times
1277
1278 The first time we get the user option
1279
1280 .. code-block:: ring
1281
1282         Option = GetChar()
1283  
1284
1285 But in the second and the third times (We accept the new line characters from the buffer)
1286
1287 .. code-block:: ring
1288
1289         GetChar() GetChar()  # End of line
1290
1291 Example : when the user select the option number 1 then press ENTER
1292
1293 We have Three Characters
1294
1295 * The first character is : Number 1
1296 * The second character is : CHAR(13)
1297 * The third character is : CHAR(10)
1298
1299 Because Windows uses CHAR(13) and CHAR(10) for each new line  ( i.e. CR+LF )
1300
1301
1302 .. index:: 
1303         pair: Frequently Asked Questions; How to use NULL and ISNULL() function?
1304
1305 How to use NULL and ISNULL() function?
1306 ======================================
1307
1308 when we try to use uninitialized variable in the Ring programming language, we get a clear runtime error message
1309
1310 Example
1311
1312 .. code-block:: ring
1313
1314         See x
1315
1316 Output
1317
1318 .. code-block:: none
1319
1320         Line 1 Error (R24) : Using uninitialized variable : x
1321         in file tests\seeuninit.ring
1322
1323 The same happens when you try to access uninitialized attributes
1324
1325 Example
1326
1327 .. code-block:: ring
1328
1329         o1 = new point
1330         see o1
1331         see o1.x
1332         class point x y z
1333
1334 Output
1335
1336 .. code-block:: none
1337
1338         x: NULL
1339         y: NULL
1340         z: NULL
1341
1342         Line 3 Error (R24) : Using uninitialized variable : x
1343         in file tests\seeuninit2.ring
1344
1345 if you want to check for the error, just use Try/Catch/End
1346
1347 .. code-block:: ring
1348
1349         Try
1350                 see x
1351         Catch
1352                 See "Sorry, We can't use x!" + nl
1353         Done
1354
1355 Output
1356
1357 .. code-block:: none
1358
1359         Sorry, We can't use x!
1360
1361 Now we will talk about NULL and ISNULL()
1362
1363 Since we get error message when we deal with uninitialized variables
1364
1365 We can check these errors using Try/Catch/Done, So we uses NULL and ISNULL() for dealing with Strings.
1366
1367 NULL is a variable contains an empty string
1368
1369 ISNULL() is a function that returns true (1) if the input is an empty string or just a string contains "NULL"
1370
1371 This because we need to test these values (empty strings) and strings contains "NULL" that sometimes come from external resource like DBMS.
1372
1373 Example
1374
1375 .. code-block:: ring
1376
1377         See IsNull(5) + nl +        # print 0
1378         IsNull("hello") + nl +      # print 0
1379         IsNull([1,3,5]) + nl +      # print 0
1380         IsNull("") + nl +           # print 1
1381         IsNull("NULL")              # print 1
1382
1383
1384 .. index:: 
1385         pair: Frequently Asked Questions; How to print lists that contains objects?
1386
1387 How to print lists that contains objects?
1388 =========================================
1389
1390 In this example we will see how we can print a list contains objects.
1391
1392 .. code-block:: ring
1393
1394         aList = [[1,2,3] , new point(1,2,3), new point(1,2,3)]
1395         see "print the list" + nl
1396         see alist
1397         see "print the item (object)" + nl
1398         see alist[2]
1399         class point x y z
1400                 func init p1,p2,p3 x=p1 y=p2 z=p3
1401
1402 Output
1403
1404 .. code-block:: none
1405
1406         print the list
1407         1
1408         2
1409         3
1410         x: 1.000000
1411         y: 2.000000
1412         z: 3.000000
1413         x: 1.000000
1414         y: 2.000000
1415         z: 3.000000
1416         print the item (object)
1417         x: 1.000000
1418         y: 2.000000
1419         z: 3.000000
1420
1421
1422 .. index:: 
1423         pair: Frequently Asked Questions; How to insert an item to the first position in the list?
1424
1425 How to insert an item to the first position in the list?
1426 ========================================================
1427
1428 To insert an item we can use the insert(aList,nIndex,Value) function.
1429
1430 .. code-block:: ring
1431
1432         aList = 1:5
1433         insert(aList,0,0)
1434         See aList # print numbers from 0 to 5
1435
1436
1437 .. index:: 
1438         pair: Frequently Asked Questions; How to print new lines and other characters?
1439
1440 How to print new lines and other characters?
1441 ============================================
1442
1443 To print new line we can use the nl variable.
1444
1445 .. code-block:: ring
1446
1447         See "Hello" + nl
1448
1449 or we can use multi-line literal as in the next example
1450
1451 .. code-block:: ring
1452
1453         See "Hello
1454         
1455         "
1456 if we want to print other characters we can use the char(nASCII) function
1457
1458 .. code-block:: ring
1459
1460         See char(109) + nl +    # print m
1461             char(77)            # print M
1462
1463 .. index:: 
1464         pair: Frequently Asked Questions; Why we don't use () after the qApp class name?
1465
1466 Why we don't use () after the qApp class name?
1467 ==============================================
1468
1469 When we use RingQt to create GUI application, we uses () after the 
1470 class name when we create new objects for example.
1471
1472 .. code-block:: ring
1473
1474         new qWidget() { setWindowTitle("Hello World") resize(400,400) show() }
1475
1476 but before doing that we create an object from the qApp class and we don't use () after that
1477
1478 .. code-block:: ring
1479
1480         Load "guilib.ring"
1481         app = new qApp
1482         {
1483             win=new qWidget()
1484             {
1485                 setwindowtitle(:test)
1486                 show()
1487             }
1488             exec()
1489         }
1490  
1491 Using () after the class name means calling the init() method in the class and passing parameters to this method.
1492
1493 If we used () while no init() method in the class we get the expected error message.
1494
1495 The class qApp don't have this method while the other classes have it because they need it to 
1496 create an object using a function that return a pointer to that object and this pointer will
1497 be stored in an attribute called pObject, for more information see ring_qt.ring file
1498 which contains the classes.
1499
1500
1501 .. index:: 
1502         pair: Frequently Asked Questions; Why the window title bar is going outside the screen?
1503
1504 Why the window title bar is going outside the screen?
1505 =====================================================
1506
1507 When we write the next code
1508
1509
1510 .. code-block:: ring
1511
1512         Load "guilib.ring"
1513         app = new qApp
1514         {
1515                 win=new qWidget()
1516                 {
1517                       setwindowtitle(:test)
1518                       setGeometry(0,0,200,200)
1519                       show()
1520                 }
1521                 exec()
1522         }
1523  
1524 I would expect that the window will run at the point (0,0) with (200,200) size but the actual 
1525 result is that the window title bar is going outside the screen.
1526
1527 This is related to the behavior of Qt framework.
1528
1529 The next code will avoid the problem
1530
1531 .. code-block:: ring
1532
1533         load "guilib.ring"
1534         new qApp {
1535                 new qWidget() {
1536                         move(0,0)
1537                         resize(200,200)
1538                         show()
1539                 }
1540                 exec()
1541         }
1542
1543
1544 .. index:: 
1545         pair: Frequently Asked Questions; How to create an array of buttons in GUI applications?
1546
1547 How to create an array of buttons in GUI applications?
1548 ======================================================
1549
1550 Check the next example:
1551
1552 .. code-block:: ring
1553
1554         Load "guilib.ring"
1555
1556         App1 = new qApp {
1557
1558                 win1 = new qWidget() {
1559                         move(0,0)
1560                         resize(500,500)
1561                         new qPushButton(win1)
1562                         {
1563                                 settext("OK")
1564                                 setclickevent("click()")
1565                         }
1566                         btn1 = new qPushButton(win1)
1567                         {
1568                                 setgeometry(100,100,100,30)
1569                                 settext("Button1")
1570                         }
1571
1572                         btn2 = new qPushButton(win1)
1573                         {
1574                                 setgeometry(200,100,100,30)
1575                                 settext("Button2")
1576                         }
1577
1578                         button = [btn1, btn2]
1579                         show()
1580                 }
1581
1582                 exec()
1583
1584         }
1585
1586         func click
1587
1588                 button[1] { settext ("Button3") }
1589                 button[2] { settext ("Button4") }
1590
1591 .. index:: 
1592         pair: Frequently Asked Questions; How to Close a window then displaying another one?
1593
1594 How to Close a window then displaying another one?
1595 ==================================================
1596
1597 This example demonstrates how to close a window and show another one
1598
1599 .. code-block:: none
1600
1601         Load "guilib.ring"
1602
1603         app=new qApp
1604         {
1605                 frmBefore=new Qwidget()
1606                 {
1607                         setWindowTitle("before!")
1608                         resize(300,320)
1609                         move(200,200)
1610
1611                         button=new qPushButton(frmBefore)
1612                         {
1613                                 setText("Close")
1614                                 setClickEvent("frmBefore.close() frmMain.show()")
1615                         }
1616
1617                         show()
1618                 }
1619
1620                 frmMain=new Qwidget()
1621                 {
1622                         setWindowTitle("After!")
1623                         resize(300,320)
1624                         move(200,200)
1625                 }
1626
1627                 exec()
1628
1629         }
1630
1631 .. index:: 
1632         pair: Frequently Asked Questions; How to create a Modal Window?
1633
1634 How to create a Modal Window?
1635 =============================
1636
1637 This example demonstrates how to create a modal window
1638
1639 .. code-block:: ring
1640
1641         load "guilib.ring"
1642         app=new qApp
1643         {
1644                 frmStart=new Qwidget()
1645                 {
1646                         setWindowTitle("The First Window")
1647                         resize(300,320)
1648                         move(200,200)
1649                 
1650                         button=new qPushButton(frmStart)
1651                         {
1652                                 setText("Show Modal Window")
1653                                 resize(200,30)
1654                                 setClickEvent("frmModal.show()")
1655                         }
1656
1657                         new qPushButton(frmStart)
1658                         {
1659                                 setText("Close Window")
1660                                 move(0,50)
1661                                 resize(200,30)
1662                                 setClickEvent("frmStart.Close()")
1663                         }
1664
1665                         show()
1666                 }
1667
1668                 frmModal =new Qwidget()
1669                 {
1670                         setWindowTitle("Modal Window")
1671                         resize(300,320)
1672                         move(200,200)
1673                         setparent(frmStart)
1674                         setwindowmodality(true)
1675                         setwindowflags(Qt_Dialog)
1676                 }
1677
1678                 exec()
1679
1680         }
1681
1682  
1683 Related Documents
1684
1685 * http://doc.qt.io/qt-5/qtwidgets-widgets-windowflags-example.html
1686 * http://doc.qt.io/qt-5/qt.html#WindowType-enum
1687 * http://doc.qt.io/qt-5/qwindow.html#setParent
1688 * http://doc.qt.io/qt-5/qt.html#WindowModality-enum
1689
1690
1691 .. index:: 
1692         pair: Frequently Asked Questions; How can I disable maximize button and resize window?
1693
1694 How can I disable maximize button and resize window?
1695 ====================================================
1696
1697 Use the method setWindowFlags()
1698
1699 .. code-block:: ring
1700
1701         Load "guilib.ring"
1702         app1 = new qapp {
1703                         win1 = new qwidget() {
1704                                         setwindowtitle("First")
1705                                         setgeometry(100,100,500,500)
1706
1707                                         new qpushbutton(win1) {
1708                                                         setgeometry(100,100,100,30)
1709                                                         settext("close")
1710                                                         setclickevent("app1.quit()")
1711                                         }
1712
1713                                         new qpushbutton(win1) {
1714                                                         setgeometry(250,100,100,30)
1715                                                         settext("Second")
1716                                                         setclickevent("second()")
1717                                         }
1718
1719                                         showmaximized()
1720                         }
1721                         exec()
1722         }
1723
1724         func second
1725                         win2 = new qwidget() {
1726                                         setwindowtitle("Second")
1727                                         setgeometry(100,100,500,500)
1728                                         setwindowflags(Qt_dialog)
1729                                         show()
1730                         }
1731
1732
1733
1734 .. index:: 
1735         pair: Frequently Asked Questions; How to use SQLite using ODBC?
1736
1737 How to use SQLite using ODBC?
1738 =============================
1739
1740 In Ring 1.1 and later versions we have native support for SQLite, so you don't need to use it through ODBC.
1741
1742 Also we can access SQLite through RingQt.
1743
1744 The answer to your question
1745
1746 .. code-block:: ring
1747
1748         pODBC = odbc_init()
1749         odbc_connect(pODBC,"DRIVER=SQLite3 ODBC Driver;Database=mydb.db;LongNames=0;"+
1750                            "Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
1751         odbc_execute(pODBC,"create table 'tel' ('ID','NAME','PHONE');")
1752         odbc_execute(pODBC,"insert into 'tel' values ('1','Mahmoud','123456');")
1753         odbc_execute(pODBC,"insert into 'tel' values ('2','Ahmed','123456');")
1754         odbc_execute(pODBC,"insert into 'tel' values ('3','Ibrahim','123456');")
1755         odbc_execute(pODBC,"select * from tel") + nl
1756         nMax = odbc_colcount(pODBC)
1757         See "Columns Count : " + nMax + nl
1758         while odbc_fetch(pODBC)
1759                 See nl
1760                 for x = 1 to nMax
1761                         see odbc_getdata(pODBC,x) 
1762                         if x != nMax see " - " ok
1763                 next
1764         end
1765         odbc_disconnect(pODBC)
1766         odbc_close(pODBC)
1767
1768 Output:
1769
1770 .. code-block:: none
1771
1772         Columns Count : 3
1773
1774         1 - Mahmoud - 123456
1775         2 - Ahmed - 123456
1776         3 - Ibrahim - 123456
1777
1778 The program will create the file : mydb.db
1779
1780 Note : when I print the odbc drivers I see the long list that includes
1781
1782 .. code-block:: none
1783
1784         SQLite3 ODBC Driver - UsageCount=1
1785         SQLite ODBC Driver - UsageCount=1       
1786         SQLite ODBC (UTF-8) Driver - UsageCount=1
1787
1788 And I'm using "SQLite3 ODBC Driver".
1789
1790
1791 .. index:: 
1792         pair: Frequently Asked Questions; Can I connect to dbase/harbour database?
1793
1794 Can I connect to dbase/harbour database?
1795 ========================================
1796
1797 You can connect to any database using ODBC
1798
1799 To connect to xbase files (*.DBF)
1800
1801 .. code-block:: ring
1802
1803         See "Using DBF Files using ODBC" + nl
1804         pODBC = odbc_init()
1805         See "Connect to database" + nl
1806         odbc_connect(pODBC,"Driver={Microsoft dBase Driver (*.dbf)};"+
1807                            "datasource=dBase Files;DriverID=277")
1808         See "Select data" + nl
1809         odbc_execute(pODBC,"select * from tel.dbf") 
1810         nMax = odbc_colcount(pODBC)
1811         See "Columns Count : " + nMax + nl
1812         while odbc_fetch(pODBC)
1813                    See "Row data:" + nl
1814                    for x = 1 to nMax
1815                                    see odbc_getdata(pODBC,x) + " - "
1816                    next
1817         end
1818         See "Close database..." + nl
1819         odbc_disconnect(pODBC)
1820         odbc_close(pODBC)
1821
1822 Output 
1823
1824 .. code-block:: none
1825
1826         Using DBF Files using ODBC
1827         Connect to database
1828         Select data
1829         Columns Count : 3
1830         Row data:
1831         Ahmad - Egypt - 234567 - Row data:
1832         Fady - Egypt - 345678 - Row data:
1833         Shady - Egypt - 456789 - Row data:
1834         Mahmoud - Egypt - 123456 - Close database...
1835
1836
1837 Also you can connect to a Visual FoxPro database (requires installing Visual FoxPro driver)
1838
1839 .. code-block:: ring
1840
1841
1842         See "ODBC test 6" + nl
1843         pODBC = odbc_init()
1844         See "Connect to database" + nl
1845         odbc_connect(pODBC,"Driver={Microsoft Visual FoxPro Driver};"+
1846                 "SourceType=DBC;SourceDB=C:\PWCT19\ssbuild\PWCTDATA\CH1\Data\mydata.dbc;") 
1847         See "Select data" + nl
1848         see odbc_execute(pODBC,"select * from t38") + nl
1849         nMax = odbc_colcount(pODBC)
1850         See "Columns Count : " + nMax + nl
1851         while odbc_fetch(pODBC)
1852                 See "Row data:" + nl
1853                 for x = 1 to nMax
1854                         see odbc_getdata(pODBC,x) + " - "
1855                 next
1856         end
1857         See "Close database..." + nl
1858         odbc_disconnect(pODBC)
1859         odbc_close(pODBC)
1860
1861 .. index:: 
1862         pair: Frequently Asked Questions; Why setClickEvent() doesn't see the object methods directly?
1863
1864 Why setClickEvent() doesn't see the object methods directly?
1865 ============================================================
1866
1867 setClickEvent(cCode) take a string contains code. The code will be executed when the event happens.
1868
1869 Ring support Many Programming Paradigms like Procedural, OOP, Functional and others.
1870
1871 But when you support many paradigms at the language level you can't know which paradigm will be used so you have two options
1872
1873 (1) Provide General Solutions that works with many programming paradigms.
1874
1875 (2) Provide Many Specific solutions where each one match a specific paradigm.
1876
1877 setClickEvent() and others belong to (General Solutions that works with many programming paradigms).
1878
1879 You just pass a string of code that will be executed without any care about classes and objects.
1880
1881 This code could be anything like calling a function, calling a method and setting variable value.
1882
1883 Some other languages force you to use OOP and call methods for events.
1884 Also some other languages uses anonymous functions that may get parameters like the current object.
1885
1886 Now we have the general solution (not restricted with any paradigm), In the future we may 
1887 add specific solutions that match specific paradigms (OOP, Functional, Declarative and Natural).
1888
1889 .. index:: 
1890         pair: Frequently Asked Questions; Why I get Calling Function without definition Error?
1891
1892 Why I get Calling Function without definition Error?
1893 ====================================================
1894
1895 Each program follow the next order 
1896
1897 1 - Loading Files
1898 2 - Global Variables and Statements
1899 3 - Functions
1900 4 - Packages, Classes and Methods
1901
1902 So what does that mean ?
1903
1904 (1) **** No Functions comes After Classes ****
1905 (2) **** No command is required to end functions/methods/classes/packages ****
1906
1907 Look at this example
1908
1909 .. code-block:: ring
1910
1911         See "Hello"
1912         test()
1913         func test 
1914             see "message from the test function!" + nl
1915         class test 
1916  
1917 In the previous example we have a function called test() so we can call it directly using test()
1918
1919 In the next example, test() will become a method
1920
1921 .. code-block:: ring
1922
1923         See"Hello"
1924         test()    # runtime error message
1925         class test
1926                 func test # Test() now is a method (not a function)
1927                         see "message from the test method!" + nl
1928
1929 The errors comes when you define a method then try calling it directly as a function.
1930
1931 The previous program must be
1932
1933 .. code-block:: ring
1934
1935         See"Hello"
1936         new test { test() }   # now will call the method
1937         class test
1938                 func test # Test() now is a method (not a function)
1939                         see "message from the test method!" + nl
1940
1941
1942 .. index:: 
1943         pair: Frequently Asked Questions; Can Ring work on Windows XP?
1944
1945 Can Ring work on Windows XP?
1946 ============================
1947
1948 Ring can work on Windows XP and load extensions without problems.
1949
1950 Just be sure that the extension can work on Windows XP and your compiler version support that (modern compilers requires some flags to support XP)
1951
1952 Check this topic
1953 https://blogs.msdn.microsoft.com/vcblog/2012/10/08/windows-xp-targeting-with-c-in-visual-studio-2012/
1954
1955 For example, We added 
1956
1957 .. code-block:: none
1958
1959         /link /SUBSYSTEM:CONSOLE,"5.01" 
1960
1961 To the batch file to support Windows XP
1962
1963 See : https://github.com/ring-lang/ring/blob/master/src/buildvccomplete.bat
1964
1965
1966 .. index:: 
1967         pair: Frequently Asked Questions; How to extend RingQt and add more classes?
1968
1969 How to extend RingQt and add more classes?
1970 ==========================================
1971
1972 You have many options
1973
1974 In general you can extend Ring using C or C++ code
1975
1976 Ring from Ring code you can call C Functions or use C++ Classes & Methods
1977
1978 This chapter in the documentation explains this part in the language
1979 http://ring-lang.sourceforge.net/doc/extension.html
1980
1981 For example the next code in *.c file can be compiled to a DLL file using the Ring library (*.lib)
1982
1983 .. code-block:: c
1984
1985         #include "ring.h"
1986
1987         RING_FUNC(ring_ringlib_dlfunc)
1988         {
1989                 printf("Message from dlfunc");
1990         }
1991
1992         RING_API void ringlib_init(RingState *pRingState)
1993         {
1994                 ring_vm_funcregister("dlfunc",ring_ringlib_dlfunc);
1995         }
1996
1997 Then from Ring you can load the DLL file using LoadLib() function then call the C function that called dlfunc() as any Ring function.
1998
1999 .. code-block:: ring
2000
2001         See "Dynamic DLL" + NL
2002         LoadLib("ringlib.dll")
2003         dlfunc()
2004
2005 Output
2006
2007 .. code-block:: none
2008
2009         Dynamic DLL
2010         Message from dlfunc
2011
2012 When you read the documentation you will know about how to get parameters like (strings, numbers, lists and objects)
2013
2014 And how to return a value (any type) from you function.
2015
2016 From experience, when we support a C library or C++ Library
2017
2018 We discovered that a lot of functions share a lot of code 
2019
2020 To save our time, and to quickly generate wrappers for C/C++ Libraries to be used in Ring
2021
2022 We have this code generator
2023
2024 https://github.com/ring-lang/ring/blob/master/extensions/codegen/parsec.ring
2025
2026 The code generator is just a Ring program < 1200 lines of Ring code
2027
2028 The generator take as input a configuration file contains the C/C++ library information
2029
2030 like Functions Prototype, Classes and Methods, Constants, Enum, Structures and members , etc.
2031
2032 Then the generator will generate
2033
2034 *.C File for C libraries (to be able to use the library functions)
2035
2036 *.CPP File for C++ libraries (to be able to use C++ classes and methods)
2037
2038 *.Ring File (to be able to use C++ classes as Ring classes)
2039
2040 *.RH file (Constants)
2041
2042 To understand how the generator work check this extension for the Allegro game programming library
2043
2044 https://github.com/ring-lang/ring/tree/master/extensions/ringallegro
2045
2046 At first we have the configuration file
2047
2048 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/allegro.cf
2049
2050 To write this file, i just used the Allegro documentation + the Ring code generator rules
2051
2052 Then after executing the generator using this batch file
2053
2054 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/gencode.bat
2055
2056 or using this script
2057
2058 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/gencode.sh
2059
2060 I get the generated source code file
2061
2062 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/ring_allegro.c
2063
2064 The generated source code file (ring_allegro.c) is around 12,000 Lines of code (12 KLOC)
2065
2066 While the configuration file is less than 1 KLOC
2067
2068 To build the library (create the DLL files)
2069
2070 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/buildvc.bat
2071
2072 Also you can check this extension for the LibSDL Library
2073
2074 https://github.com/ring-lang/ring/tree/master/extensions/ringsdl
2075
2076 After this know you should know about
2077
2078 1 - Writing the configuration file 
2079
2080 2 - Using the Code Generator 
2081
2082 3 - Building your library/extension
2083
2084 4 - Using your library/extension from Ring code
2085
2086 Let us move now to you question about Qt
2087
2088 We have RingQt which is just an extension to ring (ringqt.dll)
2089
2090 You don't need to modify Ring.
2091
2092 (1) You just need to modify RingQt
2093
2094 (2) Or extend Ring with another extension based on Qt (but the same Qt version)
2095
2096 For the first option see the RingQt extension
2097
2098 https://github.com/ring-lang/ring/tree/master/extensions/ringqt
2099
2100 Configuration file
2101
2102 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/qt.cf
2103
2104 To generate the source code
2105
2106 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencode.bat
2107
2108 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencode.sh
2109
2110 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencodeandroid.bat
2111
2112 To build the DLL/so/Dylib files
2113
2114 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildmingw32.bat
2115
2116 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildgcc.sh
2117
2118 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildclang.sh
2119
2120 Study RingQt
2121
2122 Learn about the options that you have 
2123
2124 (1) wrapping a Qt class directly
2125
2126 (2) Creating a new class then wrapping your new class 
2127
2128 For the second option (in the previous two points or in the two points before that)
2129
2130 You will create new classes in C++ code
2131
2132 Then you merge these classes to RingQt or provide special DLL for them (your decision)
2133
2134 If your work is general (will help others) just put it to RingQt.
2135
2136 if your work is special (to specific application) just put it in another extension.
2137
2138 .. index:: 
2139         pair: Frequently Asked Questions; How to add Combobox and other elements to the cells of a QTableWidget?
2140
2141 How to add Combobox and other elements to the cells of a QTableWidget?
2142 ======================================================================
2143
2144 Check the next code
2145
2146 .. code-block:: ring
2147
2148         Load "guilib.ring"
2149         New qApp 
2150         {
2151                 win1 = new qMainWindow() {
2152                         setGeometry(100,100,1100,370)
2153                         setwindowtitle("Using QTableWidget")
2154
2155                         Table1 = new qTableWidget(win1) {
2156                                 setrowcount(10) setcolumncount(10)
2157                                 setGeometry(0,0,800,400)
2158                                 setselectionbehavior(QAbstractItemView_SelectRows)
2159                                 
2160                                 for x = 1 to 10
2161                                         for y = 1 to 10
2162                                                 item1 = new qtablewidgetitem("R"+X+"C"+Y)
2163                                                 setitem(x-1,y-1, item1)
2164                                         next
2165                                 next
2166
2167                                 cmb = new QComboBox(Table1) {
2168                                         alist = ["one","two","three","four","five"]
2169                                         for x in aList additem(x,0) next   
2170                                 }
2171                                         setCellWidget(5, 5, cmb)
2172                         }
2173
2174                         setcentralwidget(table1)
2175                         show()
2176                 }
2177                 exec()
2178         }
2179         
2180 .. index:: 
2181         pair: Frequently Asked Questions; How to perform some manipulations on selected cells in QTableWidget?
2182
2183 How to perform some manipulations on selected cells in QTableWidget?
2184 ====================================================================
2185
2186 Check the next sample
2187
2188 .. code-block:: ring
2189
2190         Load "guilib.ring"
2191         
2192         New qApp {
2193                 win1 = new qMainWindow() {
2194                         setGeometry(100,100,800,600)
2195                         setwindowtitle("Using QTableWidget")
2196                         Table1 = new qTableWidget(win1) {
2197                                 setrowcount(10) setcolumncount(10)
2198                                 setGeometry(10,10,400,400)
2199                                 for x = 1 to 10
2200                                         for y = 1 to 10
2201                                                 item1 = new qtablewidgetitem("10")
2202                                                 setitem(x-1,y-1,item1)
2203                                         next
2204                                 next
2205                         }
2206                         btn1 = new qPushButton(win1) {
2207                                 setText("Increase")    
2208                                 setGeometry(510,10,100,30)
2209                                 setClickEvent("pClick()")
2210                         }
2211                         show()
2212                 }
2213                 exec()
2214         }
2215
2216         func pClick
2217                 for nRow = 0 to Table1.rowcount() - 1
2218                         for nCol = 0 to Table1.columncount() - 1
2219                                 Table1.item(nRow,nCol)  {
2220                                         if isSelected()
2221                                                 setText( "" + ( 10 + text()) )
2222                                         ok
2223                                 }
2224                         next
2225                 next
2226
2227 .. index:: 
2228         pair: Frequently Asked Questions; Which of 3 coding styles are commonly used or recommended by the community?
2229
2230 Which of 3 coding styles are commonly used or recommended by the community?
2231 ===========================================================================
2232
2233 (1) Just select any style of them but don't mix between the different styles in the same project
2234      or at least in the same context (Implementation, Tests, Scripts, etc)
2235
2236 .. Note:: State the rules in the start of each project and follow it.
2237
2238 (2) You can create your style (by changing keywords) - The idea is about customization and freedom.
2239
2240 .. Note:: It's better to change keywords and create new style only for a clear reason like using another natural  language (Arabic, French, etc.)
2241
2242 (3) The First style is better (IMHO) for questions, tutorials and small applications/programs (Less than 5,000 LOC)
2243       Example : Ring Book, Most of Ring Samples and Applications.
2244
2245 (4) The Third style is better(IMHO) for large applications and mainstream programmers
2246
2247         Example (Form Designer) : https://github.com/ring-lang/ring/tree/master/applications/formdesigner
2248