-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRubyCrashCourse.rb
More file actions
1557 lines (1099 loc) · 40.9 KB
/
RubyCrashCourse.rb
File metadata and controls
1557 lines (1099 loc) · 40.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Ruby ignores whitespaces in expressions unless they’re a part of a string. For example, an expression like 5 + 5 is the same as 5+5 and would be interpreted as such.
puts "hellow world" # Creates new line after text
p "Hellow world" # Does create new line as well and prints arrays in brackets
print "Hello" # print does not create new line and will print arrays in brackets
print "World"
=begin
This is multi-
line comment
=end
=begin
Variables beginning with a capital letter are called constants.
The value of a constant variable cannot be changed once it has been assigned.
=end
x = 8
X = 9
y = 2
puts x
print x
#outputs 8
puts X
age = 21
# To insert the value of a variable into a double quote string (a string is a sequence of characters, such as "Hello"), use the # symbol and curly brackets with the variable name.
puts "He is #{age} years old"
# Math
puts x + y
puts y - x
puts x/y
puts x*y
a = 2
b = 5
puts a**b
# Shorthand for operators
x += y # x=x+y
x -= y # x=x-y
x *= y # x=x*y
x /= y # x=x/y
x %= y # x=x%y
x **= y # x=x**y
u, j, k = 1, 2, 3
puts u
puts j
puts k
puts u + j + k
text = "Nick\'s World"
text2 = "Nick\'s \nWorld"
puts text
puts text2
puts "#{text} times #{u * j * k}"
#Use "gets" to get input from user in Ruby returns what user types as string also in includes the new line at the end as well, if you want to not include new line use "gets.chomp"
#x = gets
puts x
#puts "Enter your name is #{x}"
puts "Enter your name"
#name = gets.chomp
#puts "Welcome, #{name}"
#Only true and false are Booleans. nil is not a Boolean. 0 is not a Boolean. The string "Hello" is not a Boolean. However, in a context where a Boolean is expected, Ruby evaluates them as Boolean (truthy and falsey).
=begin
If you try to evaluate a value other than true or false as a Boolean, Ruby will automatically treat it as a Boolean. When this is done, a non-Boolean value that evaluates to true is called "truthy" and a non-Boolean value that evaluates to false is called "falsey".
=end
#There is also the .eql? method, which results in true only if both arguments have the same type and equal values.
puts 3 == 3.0 #True
# but
puts 3.eql?(3.0) # false
# Lexicographically (the alphabetical order of words is based on the alphabetical order of their component letters)
a = "Nick"
b = "Mike"
puts a > b
# if statements end in "end"
a = 42
if a > 7
puts "Greater indeed"
end
=begin
if expressions can be nested, one inside the other.
This means that the inner if is the code part of the outer one. This is one way to see whether multiple conditions are satisfied. Keep in mind that once an if condition fails, the entire block is exited.
=end
num = 18
if num == 18
puts "Equal"
if num > 17
puts "Also Greater than 17"
end
end
# The end keyword is only needed for the if statement, as the else block is part of the if expression.
num = 20
if num > 21
puts "Great than 21"
else
puts "Less than 21"
end
num = 30
if num == 3
puts "Equal to 3"
elsif num < 21
puts "Greater than 21"
elsif num == 30
puts "Equal to 30"
else
puts "Not equal 30, greater than 21, or equal 3"
end
# The unless expression is the opposite of an if expression. It executes code when a conditional is false.
num = 90
unless num != 90
puts "Equal to 90"
end
num = 90
puts "Yes" if num > 80
puts "No" unless num < 80
=begin Logical operators are used to form more complex criteria that test more than one condition for an if expression.
Ruby has three logical operators: and (&&), or (||), and not (!).
=end
num = 50
if num > 40 && num < 60
puts "Inbetween 40 and 60"
end
=begin
You can chain together multiple conditions with the logical operators to check for multiple conditions. Parentheses can be used to group together separate conditions for clarity and to control the order of operations. For example:
(a>b && b < 100) || (a<b && b > 100)
=end
=begin
As we have seen in the previous lessons, we can check for multiple conditions using the if/elsif/else expression.
A more simplified and flexible option is the case expression, which tests a value in when statements.
=end
n = 8
case n
when 7
puts "One"
when 6
puts "Six"
when 8
puts "Equal to 8"
end
# Case can be used with multiple values being tested
n = 8
case n
when 1,2,3,4
puts "First 4 numbers"
when 5,6,7,8
puts "Last 4 numbers"
end
# else can be used with case as well
n = 10
case n
when 1,2,3,4
puts "Not a guy"
when 6,7,8,9
puts "Not a girl"
when 5,11,12,13
puts "Not a human"
else
puts "Alien being"
end
=begin
Loops are used to execute the same block of code a specified number of times.
The while loop executes a block of code while its condition is true.
=end
x = 0
while x < 100
puts x
x += 1
end
# The until loop is the opposite of a while loop: it will run while its condition is false.
a = 0
until a > 100
puts "a = #{a}"
a += 1
end
=begin
A range represents a sequence. 0 to 10, 56 to 82, and a to z are all examples of ranges.
Ruby has special operators to create ranges with ease.
These are the ''..'' and ''...'' range operators. The two-dot form creates an inclusive range, while the three-dot form creates a range that excludes the specified high value.
=end
n = (1..10).to_a
puts n
n = (1...10).to_a
puts n
# can also use case and when statemnts with ranges
n = 10
case n
when 1..4
puts "Not a guy"
when 6..9
puts "Not a girl"
when 1...10
puts "Not a human"
when 7..11
puts "Alien being"
end
=begin
The for loop is a useful statement when you need to loop over a specific set of values, for example, a range.
The for loop consists of an empty variable and a range. At each iteration of the loop, the empty variable will be assigned the corresponding element of the range.
=end
for i in 1..10
puts "i = #{i}"
end
#Break statements can be used to stop loops
for i in 1...1000
puts "i = #{i}"
break if i == 88
end
=begin
Similarly, the next statement can be used to skip one iteration of the loop and continue with the next one.
*Ruby also has the redo statement, which causes the current loop iteration to repeat.
*The retry statement causes the whole loop to start again from the beginning.
=end
for m in (1..10)
next if m %2 == 0
puts "m = #{m}"
end
=begin
Another looping statement in Ruby is the loop do statement.
It allows code to execute until a break condition is achieved.
=end
x = 0
loop do
puts "x = #{x}"
x += 2
break if x > 8
end
=begin
An Array is essentially a list of numbered items.
The items are declared in a comma-separated list and enclosed in square brackets.
=end
items = ["Iphone", "Table", "Garden Hose"]
p items
# Each item has its own unique index with the first item at index zero.
items = ["Iphone", "Table", "Garden Hose"]
puts "Here are 2 items from my list #{items[0..1]}"
# can assign an element in an array a new value
items = ["Iphone", "Table", "Garden Hose"]
items[1] = "Desk"
puts "New item for index 1 = #{items[1]}"
puts "#{items}"
# arrays can contain different tpyes of elements, you can also add new elements to end of the array using << operator
arr = ["Nick", 19, 6.0, true]
puts arr[0]
puts arr[1]
puts arr[3]
arr << "Mike"
arr << false
puts "#{arr}"
# the push methdo adds an element to the end of the array
arr = ["Nick", 19, 6.0, true]
p arr
arr.push "E3"
p arr
# The pop method removes the last element of the array.
arr = ["Nick", 19, 6.0, true]
p arr
arr.pop
p arr
# use delete_at method to specify the index of the alement to be removed
arr = ["Nick", 19, 6.0, true]
p arr
arr.delete_at(2)
p arr
# You can access a range within an array using range operators .. and ...
arr = ["Nick", 19, 6.0, true]
p arr
p arr[1..3]
p arr[0...3]
# you can add arrays using + operator or subtract using - operator
a = [1,2,3,4]
b = [5,6,7,8]
c = a + b
p c
d = c - a
p d
# The & operator returns a new array containing the elements common to the two arrays, with no duplicates.
a = [1,7,3,3]
b = [5,1,9,7]
p a & b
# The | operator returns a new array by joining the arrays and removing duplicates.
a = [1,3,4]
b = [3,5,4,1]
p b || a
=begin
The reverse method returns a new array containing the original array elements in reverse order.
You can also reverse the array in place using the reverse! method
*If you use the reverse method without (!) and don’t save it to a new variable, it will just reverse it once and keep the original value.
=end
a = [1,2,3,4]
a.reverse # doesn't keep the values
p a
a.reverse! # keeps the values in variable
p a
=begin
Useful array methods:
array.length or array.size returns the number of elements in array.
array.sort returns a new array with the elements sorted
array.uniq returns a new array with duplicate values removed from array.
array.uniq! removes duplicates in place.
array.freeze safeguards the array, preventing it from being modified.
array.include?(obj) returns true if obj is present in array, false otherwise.
array.min returns the element with the minimum value.
array.max returns the element with the maximum value.
=end
=begin
Hashes (sometimes known as associative arrays, maps, or dictionaries) are similar to arrays in that they are an indexed collection of elements.
However, while you index arrays with integers, you can index a hash with anything.
That is very useful when you want to map values, for example: "name" => "David". Here, "name" is the index (also called the key) which is mapped to the value "David". So, hashes represent key=>value pairs.
A hash is created with comma separated keys and values inside curly brackets
*** Compared with arrays, hashes have one significant advantage: they can use any object as an index, even an array. For example: { [1,"jan"] => "January" }
=end
n = {"Name" => "Nick"}
puts n["Name"]
=begin
Symbols are similar to strings, but they are immutable, meaning that they cannot be changed.
A symbol is created using a colon and a name for example: a = :id
^^^^ In the code above :id is a symbol. You can also think of :id as meaning the name of the variable id, and plain id as meaning the value of the variable.
**** So why use symbols instead of strings? Using symbols not only saves time when doing comparisons, but also saves memory, because they are only stored once.
=end
n = {:name => "Nick", :age => 27, :gender => "male"}
puts n[:name]
n = {name:"Nick", age:27, gender:"male"}
puts n[:gender]
=begin
There are useful methods available for manipulating hashes:
hash.delete(key) removes the key-value pair from hash by key.
hash.key(value) returns the key for the given value in hash, nil if no matching value is found.
hash.invert creates a new hash, reversing keys and values from hash; that is, in the new hash, the keys from hash become values and values become keys.
hash.keys returns a new array with keys from hash.
hash.values returns a new array containing all the values of hash.
hash.length returns the length of hash as an integer.
=end
car = {brand:"Audi", model:"S6", color:"Black", numofwheels:4}
car.delete(:numofwheels)
puts car.values
# Nested arrays
arr = [[[1],2,3], [4,5,6]]
puts arr[0][0][0]
puts arr[0][1]
cars = {
BMW: {make: "M550i", color: "Saphire Blue", price: "$96,000"},
Audi: {make: "RS7", color: "Space Gray", price: "$127,000"},
Mercedes: {make: "E63 AMG", color: "British Racing Green", price: "$132,000"}
}
puts cars[:BMW][:make]
=begin
Ruby provides more elegant looping methods called iterators. Iterators are used to create loops.
The each iterator is one of the most used ones:
=end
names = ["Nick", "Mike", "Chris", "Tomas"]
names.each do |x| # <------ block paramenter which takes form of the variables being itterated over
puts x
end
=begin
The syntax might seem confusing at first, but you just need to remember the pipe symbols around the variable. The each iterator loops through all elements of the array and assigns the corresponding element to the variable inside the pipes with each iteration. This variable is called the block parameter.
=end
cars = {
BMW: {make: "M550i", color: "Saphire Blue", price: "$96,000"},
Audi: {make: "RS7", color: "Space Gray", price: "$127,000"},
Mercedes: {make: "E63 AMG", color: "British Racing Green", price: "$132,000"}
}
cars.each do |key, value|
puts "#{key}=>#{value}"
end
=begin
In the example above, key and value are variables that get assigned to the corresponding values of the hash elements at each iteration. You can use any name for your variables.
The do and end keywords specify a block of code in Ruby.
After the opening of the block, we have the block parameters within pipes ( | | ).
Ruby provides a shorthand way of writing blocks: you can use curly braces to start and end code blocks.
=end
cars = {
BMW: {make: "M550i", color: "Saphire Blue", price: "$96,000"},
Audi: {make: "RS7", color: "Space Gray", price: "$127,000"},
Mercedes: {make: "E63 AMG", color: "British Racing Green", price: "$132,000"}
}
cars.each {|key, value| puts "#{key}:#{value}"}
# The each iterator can also be used on ranges.
# For strings, you can use the each_char iterator to iterate over the characters.
=begin
There are also iterators available for numbers.
The times iterator executes a loop the specified number of times
=end
2.times do
puts cars[:BMW]
end
# Letter Frequency, count the frequency of letters (number of occurrences) first we lower the case of the string to easily match letters with
text = " I am learning Ruby, and it's similar yet differnet to Python"
text.downcase!
# next create the hash that will hold the letters using the default method which is used to set the default value for the hash, meaning that any key that does not have a value assigned will be set to that value.
freqs = {}
freqs.default = 0
# now we need ot iterate over each character in the string and calculate the number of occurrences in the has. We can use each_char iterator
text.each_char { |char| freqs[char] += 1}
("a".."z").each {|x| puts "#{x} : #{freqs[x]}" }
=begin
In the previous lessons we have seen some examples of methods, such as the reverse method for arrays.
A method is a set of statements that perform a specific task.
You can define your own methods to perform your desired tasks.
The def keyword is used to define a method.
*** The method name should start with a lowercase letter, so it will not be confused with constants.
=end
def say
puts "Hi"
end
# A method declaration can include parameters, which you define inside parentheses after the method name. The parameter value itself is called an argument
def add(x)
puts x+x
end
add(2)
def add(x,y)
puts x+y
end
add(2,5)
def add(x=7,b)
puts x+b
end
b = 3
add(b)
def add x, h=8
puts x+h
end
x = 2
add(x)
# can also define methods to take any number of arguments using * if nothing is put into the argument for the * parameter than it will return nothing, this is also known as an optional parameter
def say(*p)
puts p
end
say("Nick", 7.0, 2)
=begin
Return keyword is use to return a value from a method
*** Any code in the method after a return statement will not execute, because a method stops executing once the return is executed.
=end
def sum(a,b)
res = a+b
return res
end
x = sum(5,24)
puts x
# you can also define multiple returns
def sum(a,b,c)
return a*a, b*b, c*c
end
arr = sum(3,4,5)
puts arr
# Even when you do not explicitly include a return statement in your method, Ruby always returns the evaluated result of the last line of the method that is executed.
def demo(a, b)
a = a-3
b = b-3
end
puts demo(5,6)
# you can chain methods together
x = 7
def sum(a)
a+a
end
sum(2).times {puts sum(x)}
# Can also pass methods as arugments to other methods
def sum(a,b)
a+b
end
def mult(a,b)
a*b
end
x = mult(sum(2,3),sum(1,4))
puts x
=begin
Variable Scope:
Scope defines where in a program a variable is accessible.
Ruby has four types of variable scope: local, global, instance and class.
Local variables are local to the code construct in which they are declared. For example, a local variable declared in a method or within a loop cannot be accessed outside of that loop or method. Local variable names must begin with either an underscore or a lowercase letter.
=end
def sum(b)
a = 2 # <--- Local variable, lives within in the method and cannot be called outside it
puts a*b
end
=begin
Global variables in Ruby are accessible from anywhere in the Ruby program, regardless of where they are declared. Global variable names are prefixed with a dollar sign ($).
*** Use of global variables is strongly discouraged. The problem with global variables is that, not only are they visible anywhere in the code, but they can also be changed from anywhere in the application. This can result in hard to find bugs.
=end
$globalvar = 4 # This is a global Variable
def change
$globalvar = 3 # Global variable is changed here
end
change
puts $globalvar
=begin
A classic example of a method that is implemented recursively is the factorial method, which finds the product of all positive integers below a specified number.
For example, 5! (5 factorial) is 5 * 4 * 3 * 2 * 1 (120). To implement this recursively, notice that 5! = 5 * 4!, 4! = 4 * 3!, 3! = 3 * 2!, and so on. Generally, n! = n * (n-1)!.
Furthermore, 1! = 1. This is known as the base case, as it can be calculated without performing any more factorials.
=end
def fact(n)
if n <= 1
1
else
n * fact(n - 1)
end
end
puts fact(4)
=begin
You can think of classes as basic outlines of what an object should be made of and what it should be able to do. (For example, an object of class Car should have a color, make and model, and be able to move).
A class in Ruby always starts with the keyword class followed by the name of the class. The name should always be in initial capitals. You terminate the class definition with the keyword end.
There is a special initialize method available for classes which gets called when an object is created.
The purpose of the initialize method is to initialize the class variables for a new object. (For example, when a Car object is created, the initialize method could set the number of tires to the value 4)
*** The initialize method is known as the constructor in other object-oriented programming languages.
=end
class Person
def initialize
puts "Hi There"
end
end
=begin
After the class and the initialize methods are defined, we can create objects of that class by using the new method. The method new is predefined in the Ruby library and does not need to be added to your class definition.
=end
class Person
def initialize
puts "Hi There"
end
end
p1 = Person.new
p2 = Person.new
=begin Objects are also called instances of a class. The process of creating objects of a class is called instantiation.
*** Note that in computing objects aren't always representative of physical items. For example, a programming object can represent a date, a time, and a bank account.
=end
=begin
An instance variable is one type of variable defined in a class.
Each object of a class has a separate copy of the instance variables.
Instance variables are preceded by the at sign (@) followed by the variable name (for example: @name)
We can, for example, pass a parameter to the initialize method and assign it to an instance variable for a new object:
=end
class Person
def initialize(name)
@name = name
end
end
p1 = Person.new("Nick")
p2 = Person.new("Mike")
=begin
*** You might wonder why we don't use local variables instead of instance variables. We need instance variables because their scope is the entire object, meaning that they are accessible inside all the methods for the object, opposed to local variables, which are accessible only within the scope they are declared, such as a single method.
=end
# A class can multiple instance variable
class Car
def initialize(brand, model, year)
@brand = brand
@model = model
@year = year
puts "#{brand}, #{model}, #{year}"
end
end
c1 = Car.new("BMW", "M550i", 2021)
c2 = Car.new("Audi", "RS7", 2021)
=begin
In the real world, objects behave in their own way. A car moves, a phone rings, and so on.
The same applies to programming objects. Behavior is specific to the object's type and is defined by methods in the class.
You can declare instance methods that are available to an object of the class.
=end
class Car
def initialize(brand, model, year)
@brand = brand
@model = model
@year = year
end
def readout
@brand
end
end
c1 = Car.new("BMW", "M550i", 2022)
c2 = Car.new("Mercedes", "E63 AMG", 2021)
puts c1.readout
puts c2.readout
=begin
Getter methods are used to access the instance variable. If we want to change the value of the instance variables, we need setter methods.
Ruby provides a special syntax for defining setter methods: the method name is followed by an equal sign (=).
=end
class Car
def initialize(brand, model, year)
@brand = brand
@model = model
@year = year
end
def set_name=(model)
@model = model
end
def readout
print "#{@brand} #{@model} #{@year}"
end
end
c1 = Car.new("BMW", "M550i", 2022)
c2 = Car.new("Mercedes", "E63 AMG", 2021)
puts c1.readout
c1.set_name = "M5"
puts c1.readout
# When you see this code, just realize there's a method called set_name= working behind the scenes.
=begin
Ruby has a built-in way to automatically create these getter and setter methods using the attr_accessor method.
The attr_accessor method takes a symbol of the instance variable name as an argument, which it uses to create getter and setter methods.
=end
class Car
attr_accessor :model
def initialize(model)
@model = model
end
end
c = Car.new("M5")
c.model = "M550i"
puts c.model
=begin
That one line replaced two accessor method definitions.
Ruby also provides the attr_reader and attr_writer methods in case only a getter or setter method is needed for the instance variable.
*** We can pass multiple symbols to the attr_accessor, attr_reader and attr_writer methods. For example: attr_accessor :name, :height, :weight
=end
=begin
Class methods are methods we can call directly on the class itself, without having to instantiate any objects.
This can be useful when there is no logical need to create an object of the class, such as when a class is used to group similar methods and functionality (like mathematical operations).
*** Remember, when used inside of instance methods, self is representing the current instance (object) of that class.
When defining class methods, self is referring to the class itself, and not to an instance of the class.
=end
class Car
def self.info
puts "A car"
end
end
Car.info
=begin
Class variables are accessible to every object of a class. A class variable belongs to the class, not the objects.
You declare a class variable using two @ signs, for example @@name.
*** Class variables are usually used when you need information about the class, not the individual objects.
=end
class Car
@@count = 0
def initialize
@@count += 1
end
def self.get_count
@@count
end
end
c1 = Car.new
c2 = Car.new
puts Car.get_count
=begin
A class can also contain constants. Remember, constant variables do not change their value and start with a capital letter. It is common to have uppercase names for constants
You can access constants using the class name, followed by two colon symbols (::) and the constant name
=end
class Calc
PI = 3.14
end
puts Calc::PI
=begin
The to_s method comes built-in with all classes. It gets called when you output the object
When we call puts p, Ruby automatically calls the to_s method for the object p, so puts p is the same as puts p.to_s
*** By default, the to_s method prints the object's class and an encoding of the object id.
=end
class Car
#some code
end
c = Car.new
puts c
=begin
We can define our own to_s method for a class and add custom implementation to it.
*** Defining the to_s method makes it easier and shorter to output the information of an object in the format needed, as opposed to defining a custom method and calling it from an object.
When you define the to_s method you call puts on your object (puts obj), where with a custom method you have to explicitly call it from the object (puts obj.info).
=end
class Car
def initialize(make, model, year)
@make = make
@model = model
@year = year
end
def to_s
"The make is a #{@year}, #{@make}, model #{@model}"
end
end
c = Car.new("Audi", "RS7", 2022)
puts c
=begin
Inheritance is when a class receives, or inherits, attributes and behavior from another class. The class that is inheriting behavior is called the subclass (or derived class) and the class it inherits from is called the superclass (or base class).
*** The < symbol is used to inherit a class from another class.
=end
class Car
def initialize(model, year)
@year = year
@model = model
end
def readout
puts "Your model is #{@model}, year #{@year}"
end
end
class BMW < Car
end
c = BMW.new("M550i", 2022)
c.readout
# BMW inehrits the readout method, but has it's own method of engine and attribute(instance variable) of body type
class Car
def initialize(model, year)
@model = model
@year = year
end
def readout
puts "Your model is #{@model}, year #{@year}"
end
end
class BMW < Car
attr_accessor :body_type
def engine
if @model == "M550i"
puts "N63 4.4L V8"
elsif @model == "M5"
puts "S63 4.4.L V8"