active-orient 0.6 → 0.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/Gemfile +4 -10
  4. data/Guardfile +4 -12
  5. data/README.md +198 -261
  6. data/VERSION +1 -1
  7. data/active-orient-0.4.gem +0 -0
  8. data/active-orient-0.41.gem +0 -0
  9. data/active-orient.gemspec +5 -6
  10. data/config/boot.rb +0 -84
  11. data/config/connect.yml +4 -8
  12. data/examples/books.rb +39 -86
  13. data/examples/streets.rb +84 -85
  14. data/lib/active-orient.rb +9 -57
  15. data/lib/base.rb +145 -172
  16. data/lib/base_properties.rb +44 -40
  17. data/lib/model.rb +468 -0
  18. data/lib/orient.rb +60 -114
  19. data/lib/query.rb +73 -71
  20. data/lib/rest.rb +1059 -0
  21. data/lib/support.rb +319 -386
  22. data/test.rb +4 -0
  23. data/usecase.md +91 -0
  24. metadata +20 -65
  25. data/bin/active-orient-console +0 -38
  26. data/config/config.yml +0 -10
  27. data/create_project +0 -19
  28. data/examples/test_commands.rb +0 -92
  29. data/examples/test_commands_2.rb +0 -54
  30. data/examples/test_commands_3.rb +0 -48
  31. data/examples/test_commands_4.rb +0 -28
  32. data/examples/time_graph.md +0 -162
  33. data/gratefuldeadconcerts.md +0 -94
  34. data/lib/class_utils.rb +0 -300
  35. data/lib/database_utils.rb +0 -106
  36. data/lib/init.rb +0 -45
  37. data/lib/java-api.rb +0 -437
  38. data/lib/jdbc.rb +0 -211
  39. data/lib/model/edge.rb +0 -55
  40. data/lib/model/model.rb +0 -91
  41. data/lib/model/the_class.rb +0 -500
  42. data/lib/model/the_record.rb +0 -322
  43. data/lib/model/vertex.rb +0 -136
  44. data/lib/orientdb_private.rb +0 -48
  45. data/lib/other.rb +0 -330
  46. data/lib/rest/change.rb +0 -137
  47. data/lib/rest/create.rb +0 -488
  48. data/lib/rest/delete.rb +0 -134
  49. data/lib/rest/operations.rb +0 -160
  50. data/lib/rest/read.rb +0 -150
  51. data/lib/rest/rest.rb +0 -112
  52. data/lib/rest_disabled.rb +0 -24
  53. data/linkmap.md +0 -75
  54. data/namespace.md +0 -111
  55. data/old_lib_functions/two_general_class.rb +0 -139
  56. data/rails.md +0 -125
  57. data/rails/activeorient.rb +0 -53
  58. data/rails/config.yml +0 -10
  59. data/rails/connect.yml +0 -17
  60. data/usecase_oo.md +0 -61
data/test.rb ADDED
@@ -0,0 +1,4 @@
1
+ $:.unshift File.expand_path('.')
2
+ require 'config/boot'
3
+
4
+
@@ -0,0 +1,91 @@
1
+ ## Usecase
2
+ Below some typical features are summarized by example
3
+
4
+ Start a irb-session and initialize ActiveOrient
5
+ ```ruby
6
+ topo@gamma:~/new_hctw$ irb
7
+ 2.2.1 :001 > require './config/boot'
8
+ Using development-environment
9
+ -------------------- initialize -------------------- => true
10
+ 2.2.1 :002 > ActiveOrient::Model.orientdb = ror = ActiveOrient::OrientDB.new
11
+ => #<ActiveOrient::OrientDB:0x000000046f1a90 @res=#<RestClient::Resource:0x000000046c0af8 @url="http://localhost:2480", @block=nil, @options={:user=>"hctw", :password=>"**"}>, @database="hc_database", @classes=[]>
12
+ ```
13
+ #### Object Mapping
14
+ Lets create a class, put some content in it and perform basic oo-steps.
15
+
16
+ Attributes(Properties) do not have to be formaly declared. However it is nessessary to introduce them properly. This is done with the »attributes«-Argument during the initialisation step or via
17
+ »update«
18
+
19
+ ``` ruby
20
+ A = r.create_class 'my_a_class'
21
+ => ActiveOrient::Model::Myaclass
22
+ a = A.new_document attributes: { test: 45}
23
+ a.update set: { a_array: aa= [ 1,4,'r', :r ] ,
24
+ a_hash: { :a => 'b', b: 2 } }
25
+ a.to_human
26
+ => <Myaclass: a_array: [1, 4, "r", :r] a_hash: {:a=>"b", :b=>2} test: 45>
27
+
28
+ ```
29
+ Then the attibutes/properties can be handled as normal ruby objects ie.
30
+
31
+ ``` ruby
32
+ a.a_array << "a new element"
33
+ a.a_hash[ :a_new_element ] = "value of the new element"
34
+ a.test += 3
35
+ a.test = 567
36
+ a.update
37
+ ```
38
+ Objects are synchronized with the database with »update«. To revert changes, a »reload!« method is available.
39
+
40
+ #### Contracts-Example
41
+ Assume a Database, which is defined as
42
+ ```
43
+ create class Industries
44
+ create class Categories
45
+ create class SubCategories
46
+ create class OpenInterest ABSTRACT
47
+ create class Stocks extends Contracts
48
+ create class Futures extends Contracts
49
+ create class Options extends Contracts
50
+ create class Forexes extends Contracts
51
+ create property Industries.categories linkset
52
+ create property Categories.subcategories linkset
53
+ create property Categories.industry link
54
+ create property SubCategories.category link
55
+ create property SubCategories.contracts linkset
56
+
57
+ create property Contracts.subcategory link
58
+ create property Contracts.details link
59
+ create property OpenInterest.contracts linkset
60
+
61
+ ```
62
+ This defines some conventional relations:
63
+
64
+ OpenInterest -> Contracts <- Subcategory <- Category <- Industry
65
+
66
+ with some oo-Behavior
67
+ ```ruby
68
+ 2.2.1 :003 > ror.class_hierachie base_class: 'Contracts'
69
+ => ["Forexes", "Futures", "Options", "Stocks"]
70
+ ```
71
+
72
+ then the following ORM-behavior is implemented:
73
+ ```ruby
74
+ topo@gamma:~/new_hctw$ irb
75
+ 2.2.1 :001 > require './config/boot'
76
+ Using development-environment
77
+ -------------------- initialize -------------------- => true
78
+ 2.2.1 :002 > ActiveOrient::Model.orientdb = ror = ActiveOrient::OrientDB.new
79
+ => #<ActiveOrient::OrientDB:0x000000046f1a90 @res=#<RestClient::Resource:0x000000046c0af8 @url="http://localhost:2480", @block=nil, @options={:user=>"hctw", :password=>"**"}>, @database="hc_database", @classes=[]>
80
+ 2.2.1 :003 > OpenInterest = ror.open_class 'Openinterest'
81
+ => ActiveOrient::Model::Openinterest
82
+ 2.2.1 :004 > first_open_interest = OpenInterest.first
83
+ => #<ActiveOrient::Model::Openinterest:0x0000000443ede8 @metadata={"type"=>"d", "class"=>"Openinterest", "version"=>5, "fieldTypes"=>"fetch_date=t,contracts=z", "cluster"=>13, "record"=>0}, @attributes={"fetch_date"=>"2015-06-02 00:00:00", "contracts"=>["#21:36", "#21:35", "#21:34", "#21:33", "#21:32", "#21:31", "#21:30", "#21:29", "#21:28", "#21:27", "#21:26", "#21:25", "#21:24", "#21:23", "#21:22", "#21:21", "#21:51", "#21:49", "#21:50", "#21:47", "#21:48", "#21:45", "#21:46", "#21:43", "#21:44", "#21:41", "#21:42", "#21:39", "#21:40", "#21:37", "#21:38", "#21:4", "#21:3", "#21:0", "#21:17", "#21:18", "#21:19", "#21:20", "#21:13", "#21:14", "#21:15", "#21:16", "#21:9", "#21:10", "#21:11", "#21:12", "#21:5", "#21:6", "#21:7", "#21:8"], "created_at"=>2015-07-01 15:27:41 +0200, "updated_at"=>2015-07-01 15:27:41 +0200}>
84
+ 2.2.1 :005 > first_open_interest.contracts.first.subcategory.category.industry
85
+ => #<ActiveOrient::Model::Industries:0x00000004af88f0 @metadata={"type"=>"d", "class"=>"Industries", "version"=>8, "fieldTypes"=>"categories=n", "cluster"=>17, "record"=>1}, @attributes={"categories"=>["#15:13", "#15:4", "#15:1"], "name"=>"Basic Materials", "created_at"=>2015-07-01 15:27:58 +0200, "updated_at"=>2015-07-01 15:27:58 +0200}>
86
+
87
+ 2.2.1 :006 > first_open_interest.contracts.first.subcategory.category.industry.name
88
+ => "Basic Materials"
89
+ ```
90
+
91
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active-orient
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.6'
4
+ version: '0.42'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hartmut Bischoff
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-02 00:00:00.000000000 Z
11
+ date: 2016-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,45 +42,31 @@ dependencies:
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: activemodel
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
45
+ - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '0'
47
+ version: '4.2'
62
48
  type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
- - - ">="
52
+ - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '0'
54
+ version: '4.2'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rest-client
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - ">="
59
+ - - "~>"
74
60
  - !ruby/object:Gem::Version
75
- version: '0'
61
+ version: '1.8'
76
62
  type: :runtime
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - ">="
66
+ - - "~>"
81
67
  - !ruby/object:Gem::Version
82
- version: '0'
83
- description: Persistent ORM for OrientDB(V.2.2), based on ActiveModel. Rails 5 compatible
68
+ version: '1.8'
69
+ description: Persistent ORM for OrientDB, based on ActiveModel
84
70
  email:
85
71
  - topofocus@gmail.com
86
72
  executables: []
@@ -94,54 +80,23 @@ files:
94
80
  - LICENSE
95
81
  - README.md
96
82
  - VERSION
83
+ - active-orient-0.4.gem
84
+ - active-orient-0.41.gem
97
85
  - active-orient.gemspec
98
- - bin/active-orient-console
99
86
  - config/boot.rb
100
- - config/config.yml
101
87
  - config/connect.yml
102
- - create_project
103
88
  - examples/books.rb
104
89
  - examples/streets.rb
105
- - examples/test_commands.rb
106
- - examples/test_commands_2.rb
107
- - examples/test_commands_2.rb~
108
- - examples/test_commands_3.rb
109
- - examples/test_commands_4.rb
110
- - examples/time_graph.md
111
- - gratefuldeadconcerts.md
112
90
  - lib/active-orient.rb
113
91
  - lib/base.rb
114
92
  - lib/base_properties.rb
115
- - lib/class_utils.rb
116
- - lib/database_utils.rb
117
- - lib/init.rb
118
- - lib/java-api.rb
119
- - lib/jdbc.rb
120
- - lib/model/edge.rb
121
- - lib/model/model.rb
122
- - lib/model/the_class.rb
123
- - lib/model/the_record.rb
124
- - lib/model/vertex.rb
93
+ - lib/model.rb
125
94
  - lib/orient.rb
126
- - lib/orientdb_private.rb
127
- - lib/other.rb
128
95
  - lib/query.rb
129
- - lib/rest/change.rb
130
- - lib/rest/create.rb
131
- - lib/rest/delete.rb
132
- - lib/rest/operations.rb
133
- - lib/rest/read.rb
134
- - lib/rest/rest.rb
135
- - lib/rest_disabled.rb
96
+ - lib/rest.rb
136
97
  - lib/support.rb
137
- - linkmap.md
138
- - namespace.md
139
- - old_lib_functions/two_general_class.rb
140
- - rails.md
141
- - rails/activeorient.rb
142
- - rails/config.yml
143
- - rails/connect.yml
144
- - usecase_oo.md
98
+ - test.rb
99
+ - usecase.md
145
100
  homepage: https://github.com/topofocus/active-orient
146
101
  licenses:
147
102
  - MIT
@@ -154,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
109
  requirements:
155
110
  - - ">="
156
111
  - !ruby/object:Gem::Version
157
- version: 2.2.5
112
+ version: 2.2.0
158
113
  required_rubygems_version: !ruby/object:Gem::Requirement
159
114
  requirements:
160
115
  - - ">="
@@ -162,8 +117,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
117
  version: '0'
163
118
  requirements: []
164
119
  rubyforge_project:
165
- rubygems_version: 2.6.8
120
+ rubygems_version: 2.4.6
166
121
  signing_key:
167
122
  specification_version: 4
168
- summary: Pure ruby client for OrientDB(V.2.2) based on ActiveModel
123
+ summary: Pure ruby client for OrientDB based on ActiveModel
169
124
  test_files: []
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env ruby
2
- ## loads the active-orient environment
3
- ## and starts an interactive shell
4
- ## Parameter: production (p)
5
- ## development (d) [default]
6
- ## test (t)
7
- require 'logger'
8
- LogLevel = Logger::WARN
9
- require File.expand_path(File.dirname(__FILE__) + "/../config/boot")
10
-
11
- require 'orientdb' if RUBY_PLATFORM == 'java'
12
- require 'yaml'
13
-
14
- puts "ORD points to the REST-Instance, Database: #{ActiveOrient.database}"
15
- puts "DB is the API-Instance of the database, DB.db gets the DB-Api-base " if RUBY_PLATFORM == 'java'
16
-
17
- puts '-'* 45
18
- ns= case ActiveOrient::Model.namespace
19
- when Object
20
- "No Prefix, just ClassName#CamelCase"
21
- else
22
- ActiveOrient::Model.namespace.to_s + "{ClassName.camelcase}"
23
- end
24
- puts "Namespace for model-classes : #{ns}"
25
- puts "Present Classes (Hierarchy) "
26
-
27
- puts ORD.class_hierarchy.to_yaml
28
- puts ""
29
- puts "Active Classes -> ActiveOrient ClassName"
30
- puts '-'* 45
31
- puts ActiveOrient::Model.allocated_classes.map{|x,y| "#{"%15s"% x} -> #{y.to_s}" }.join("\n")
32
- puts '-'* 45
33
-
34
- include OrientDB
35
-
36
- require 'irb'
37
- ARGV.clear
38
- IRB.start(__FILE__)
@@ -1,10 +0,0 @@
1
- ---
2
- :active_orient:
3
- ## Namespace: Prefix of Model-Objects. :self -> ActiveOrient::Model::{name}
4
- ## :object => No Prefix
5
- ## :active_orient => ActiveOrient::{name}
6
- :namespace: :object
7
- ## model_dir: Path to model-files relative to the root of the application
8
- ## ie. app/model or model
9
- :model_dir: 'lib/model'
10
-
@@ -1,19 +0,0 @@
1
- # create a dir bin
2
- # and move bin/activeorient-console.sh into that dir
3
-
4
- # create a dir config
5
- # and create a sample connect.yml
6
- # and copy boot.rb
7
-
8
- # create a schema dir
9
- # and put stuff to administrate the database-structure there
10
-
11
- # create a dir model
12
- # and put a sample model-file into it
13
- # create model-files according to the database-schema
14
-
15
- # create a dir spec
16
- # and copy spec-helper.rb into it
17
-
18
- # create a Guard and a Gemfile in the root-directory
19
-
@@ -1,92 +0,0 @@
1
- require 'awesome_print'
2
- require_relative "../lib/active-orient.rb"
3
-
4
- # Start server
5
- ActiveOrient::OrientDB.default_server = { user: 'root', password: 'tretretre' }
6
-
7
- # Select database
8
- r = ActiveOrient::OrientDB.new database: 'NewTest'
9
- r.delete_database database: 'NewTest'
10
- r = ActiveOrient::OrientDB.new database: 'NewTest'
11
-
12
- print "\n"+"*"*20+"DATABASE"+"*"*20+"\n"
13
-
14
- print "#{r.get_resource} \n" # <--- See the address of the server
15
- print "#{r.get_databases} \n" # <--- List available databases
16
-
17
- # r.create_database(database: "Onetwothree") # <--- Create a new database
18
- print "#{r.database} \n" # <--- See the working database
19
-
20
- # r.delete_database database: "Onetwothree" # <--- Delete an old database
21
-
22
- print "\n"+"*"*20+"CLASSES"+"*"*20+"\n"
23
-
24
- ap r.get_classes, :indent => -2 # <--- See available classes
25
- print "#{r.get_classes 'name'} \n" # <--- See the names of the available classes
26
-
27
- print "#{r.class_hierarchy} \n" # <--- See hierarchy of the classes
28
- print "#{r.class_hierarchy base_class: 'V'} \n" # <--- See hierarchy under V (Vectors classes)
29
- print "#{r.class_hierarchy base_class: 'E'} \n" # <--- See hierarchy under E (Edges classes)
30
-
31
- print "#{r.database_classes} \n" # See classes without including System classes
32
- print "#{r.database_classes include_system_classes: true} \n " # See classes including System classes
33
- print "#{r.inspect_classes} \n" # Same as r.database_classes
34
-
35
-
36
- doc1 = r.create_class "DocumentTest" # Create Document/Vertex/Edge class
37
- doc2 = r.create_class "DocumentArriveTest"
38
- ver1 = r.create_vertex_class "VertexTest"
39
- ver2 = r.create_vertex_class "Vertex_ArriveTest"
40
- edg1 = r.create_edge_class "EdgeTest"
41
- ver1 = r.open_class "VertexTest" # Same as create_class
42
-
43
- print "\n"+"*"*20+"RECORDS"+"*"*20+"\n"
44
-
45
- a = doc1.create name: "Doc1"
46
- a2 = doc1.create name: "Doc12"
47
- b = doc2.create name: "Doc2"
48
- b2 = doc2.create name: "Doc22"
49
- aver = ver1.create vname: "Ver1"
50
- aver2 = ver1.create vname: "Ver12"
51
- bver = ver2.create vname: "Ver2"
52
- bver2 = ver2.create vname: "Ver22"
53
-
54
- edg1.create_edge attributes: {famname: "edg1"}, from: aver, to: [bver, bver2], unique: true
55
- nex = edg1.create_edge attributes: {familyname: "edg2"}, from: aver, to: [bver, bver2], unique: true # <--- We don't overwrite since we select a unique
56
- nex1 = edg1.create_edge attributes: {familyname: "edg3"}, from: aver, to: [bver, bver2]
57
- nex2 = edg1.create_edge attributes: {familyname: "edg4"}, from: aver, to: [bver, bver2]
58
-
59
- print "#{nex1}"
60
- print "\n\n BVER = #{bver.rid} \n" # Check the RID of the vertex
61
- r.delete_edge nex1, nex2 # Used to delete edges
62
- r.delete_class doc2 # Used to delete a class
63
- doc2 = r.create_class "Document_Arrive_Test"
64
-
65
- print "\n"+"*"*20+"PROPERTY"+"*"*20+"\n"
66
-
67
- r.create_property doc2, :name, type: :string, index: :string #add one property
68
- doc2.create_property :familyname, type: :string, index: :string #the same but starting directly from the class
69
- r.create_properties doc2, {age: {type: :integer}, address: {type: :string}} #add more properties
70
- doc2.create_properties({feetsize: {type: :integer}, country: {type: :string}})
71
- b = doc2.create name: "Lucas", age: 91 #add more properties directly from the class
72
-
73
- print "\n"+"*"*20+"\n"
74
- r.delete_property doc2, "age" #delete one property
75
- doc2.delete_property "country" #delete one property directly from the class
76
- print "\n"+"*"*20+"\n"
77
-
78
- ap r.get_class_properties doc2 #get the properties of a class
79
- ap doc2.get_class_properties #get the properties of a class directly from the class
80
-
81
- print "\n"+"*"*20+"\n"
82
-
83
- r.print_class_properties doc2 #get the properties of a class in nice way
84
- doc2.print_class_properties #get the properties of a class in nice way directly from the class
85
-
86
- gg = r.create_document doc2, attributes: {name: "Test"}
87
- hh = doc2.create_document attributes: {name: "Code"}
88
-
89
- r.delete_document gg, hh # delete a document from database
90
- doc2.delete_document hh # delete a document from a class
91
-
92
- r.create_index doc2, name: "name" #Create index
@@ -1,54 +0,0 @@
1
- require 'awesome_print'
2
- require_relative "../lib/active-orient.rb"
3
-
4
- # Start server
5
- ActiveOrient::OrientDB.default_server= { user: 'root', password: 'tretretre' }
6
-
7
- # Select database
8
- r = ActiveOrient::OrientDB.new database: 'NewTest'
9
-
10
- #r.delete_class "Document_Test"
11
- doc1 = r.create_class "DocumentTest" # Create Document/Vertex/Edge class
12
- doc2 = r.create_class "DocumentArrive_Test"
13
- ver1 = r.create_vertex_class "VertexTest"
14
- ver2 = r.create_vertex_class "VertexArriveTest"
15
- edg1 = r.create_edge_class "EdgeTest"
16
- ver1 = r.open_class "VertexTest" # Same as create_class
17
-
18
- par = r.get_documents from: "DocumentTest", where: {name: "Doc1"} # Get documents
19
- par = doc1.get_documents where: {name: "Doc1"} # Same as above
20
- print "0 "
21
- ap par, :indent => -2
22
-
23
- num = r.count_documents from: "DocumentTest", where: {name: "Doc1"}
24
- num2 = doc1.count where: {name: "Doc1"}
25
- print "\n1 COUNT: #{num2} \n\n"
26
-
27
- r.create_or_update_document doc1, set: {familyname: "John"}, where: {name: "Doc1"}
28
- r.update_or_create_documents doc1, where: {name: "Doc1"}, set: {age: 91}
29
- doc1.update_or_create_documents where: {name: "Doc1"}, set: {age: 91}
30
- doc1.update_or_create_documents where: {name: "Doc2"}, set: {age: 91}
31
- par = doc1.get_documents where: {name: "Doc1"}
32
- #ap par, :indent => -2
33
-
34
- print "2 #{par[0].attributes} \n\n" # Access attributes
35
- print "3 #{par[0].metadata} \n\n" # Access metadata
36
-
37
- r.delete_documents doc1, where: {name: "Doc2"}
38
- doc1.delete_documents where: {name: "Doc2"}
39
-
40
- a = r.get_document "1:0" # Get by RID
41
-
42
- r.patch_document "1:0" do {name: "is a test"} end
43
-
44
- r.update_documents doc1, set: {age: 191}, where: {name: "Doc1"} # Update a document
45
- doc1.update_documents set: {age: 191}, where: {name: "Doc1"}
46
-
47
- a = r.execute "Document_Test" do # To execute commands
48
- [{type: "cmd", language: 'sql', command: "SELECT * FROM DocumentTest WHERE name = 'Doc1'"}]
49
- end
50
- print "\n4 #{a} \n \n"
51
-
52
- a = r.classname doc1
53
- a = doc1.classname
54
- print "5 #{a} \n \n"