2024-04-04

This commit is contained in:
2024-04-04 13:44:51 +09:00
parent d444640770
commit fabe7642fa
40 changed files with 2423 additions and 0 deletions

11
.project Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ruby-examples</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

20
doc/class.md Normal file
View File

@@ -0,0 +1,20 @@
# 클래스
```ruby
#!/usr/bin/ruby
class Person
def initialize(first_name, last_name, age)
@first_name = first_name
@last_name = last_name
@age = age
end
def name
"#@first_name #@last_name"
end
end
steve = Person.new("Steve", "McQueen", 37)
puts steve.name
```

113
src/01_literal.rb Executable file
View File

@@ -0,0 +1,113 @@
#!/usr/bin/ruby
# 진위형
v = nil # `nil`은 null 또는 unknown입니다.
v = false #`nil`과 `false` 모두 거짓입니다.
v = true # `true`와 그 외의 값들은 모두 참입니다.
# 숫자형
## 정수형
i = 1234
i = 1_234 # 읽기 쉽게 끊어 쓰기도 할 수 있어요.
h = 0xaa # 16진수
o = 0o252 # 8진수
b = 0b10101100 # 2진수
d = 0d170 # 0d로 시작하면 10진수입니다.
## 부동소수형
f = 12.34
f = 1.234e-2 # 지수 표현
## 유리수형: 값 뒤에 'r'을 븥입니다.
r = 2/3r # 2/3
r = 1.5r
## 복소수형: 허수 값 뒤에 'i'를 붙입니다.
c = 1i # 0 + 1i
# 문자열
s = "이것은 문자열이다.\n" # 이스케잎 문자도 처리됩니다.
s = '이것도 문자열입니다.' # 이스케잎 문자는 처리 안됨
s = %q{이 역시도 문자열입니다.} # 이스케잎 문자는 처리 안됨
s = %Q{또 문자열입니다.} # 이스케잎 문자도 처리됨
s = %{그리고 또 문자열입니다.} # 이스케잎 문자도 처리됨
s = <<DOC
,
.
DOC
puts s
## 보간
price = 100
s = "가격은 #{price}입니다." # 변수 값이 동적으로 문자열에 삽입됩니다.
## 결합
s = "Apple" "Banana" "Carrot" # 인접한 문자열은 하나의 긴 문자열로 합쳐집니다.
## 문자 하나
ch = ?갑 # '?'로 시작해서 하나의 문자로만 이루어진 문자열을 나타냅니다.
# 심볼
:"my_symbol"
%s{my_symbol}
# 배열
array = [1, 2, 3]
%w{apple banana carrot} # 문자열 배열. 보간 안됨
%W{apple banana carrot} # 보간 처리됨
%i{foo bar} # 심볼 배열을 나타냅니다.
%I{foo bar}
# 해시
hash = {"one"=>1, "two"=>2, "three"=>3} # 해시는 키/값 쌍을'{}'로 묶어서 표현합니다.
hash = {one:1, two:2, three:3} # 이렇게도 쓸 수 있습니다.
# 레인지
(1..10) # 1 ~ 10까지
(1...10) # 1 ~ 9까지
# 정규표현식
re = /foo/ # 정규표현식은 '/'로 묶어서 표현합니다.ARGF
%r{foo}
# 람다
-> {1 + 1}
-> (v) { 1 + v }
# 백틱
%x{echo Hello} # 쉘 명령을 실행할 때 사용됩니다.
END{
# https://ruby-doc.org/3.2.2/syntax/literals_rdoc.html
}

16
src/02_variable.rb Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/ruby
v = 5
=begin
* 지역 변수 : 지역 변수의 이름은 소문자와 '_'로 구성합니다.
* 인스턴스 변수 : 인스턴스 변수는 '@'으로 시작합니다.
* 클래스 변수 : 클래스 변수는 '@@'으로 시작합니다.
* 전역 변수 : 전역 변수는 '$'로 시작합니다.
=end
END{
# https://ruby-doc.org/3.2.2/syntax/assignment_rdoc.html
}

115
src/03_control_flow.rb Executable file
View File

@@ -0,0 +1,115 @@
#!/usr/bin/ruby
a = 100
# if
if a == 100 then
puts "It's 100."
end
if a == 100 # 'then'은 생략해도 됩니다.
puts "It's 100."
end
if a == 100 then # if - else
puts "It's 100."
else
puts "It's not 100."
end
if a == 100 then # if - elsif - else
puts "It's 100."
elsif a == 200 then
puts "It's 200."
else
puts "It's not 100 nor 200."
end
# 삼항연산자 ?:
v = (a==100) ? 1 : 2;
# unless
unless a==10 then # 물론 then은 생략할 수 있고요. else문도 함깨 사용할 수 있습니다.
puts "not 10!"
end
# if / unless 모디파이어
a += 1 if a.zero? # if나 unless를 표현식의 뒤에 붙여 사용할 수 있습니다.
a -=1 unless a.zero?
# case - when
case a # switch-case 가 아니라 case-when입니다.
when 1,2 then puts "Need more"
when 3 then puts "Ok."
else puts "Enough."
end
case "1234"
when /^1/ then # 정규표현식을 사용해봅시다.
puts "It starts with one."
else
puts "It's not start with one."
end
# while
while a<10 do # 'do'는 생략해도 됩니다.
a++
end
# until
until a>10 do # 'do'는 생략해도 됩니다.
a++
end
# for-in
for value in [1,2,3] do # 'do'는 생략해도 됩니다.
puts value
end
# while / until 모디파이어
a += 1 while a<10
a -=1 until a<10
begin
a += 1
end while a<10 # begin-end 블록으로 묶으면 가독성이 향상됩니다.
# break / next / redo
while true do
# do something
next if a.even? # next를 사용해서 다음 차례로 진행합니다.
redo if b=100 # redo는 현재 차례를 다시 한 번 반복합니다.
break if a<10 # break를 사용해서 루프를 벗어납니다.
end
# loop
loop do
# do something
end
END{
# https://ruby-doc.org/3.2.2/syntax/control_expressions_rdoc.html
}

88
src/04_method.rb Executable file
View File

@@ -0,0 +1,88 @@
#!/usr/bin/ruby
# 메서드
def do_something
puts "Hello"
end
=begin
* 메서드 이름은 소문자와 숫자, 밑줄문자등을 사용합니다. 유니코드 문자도 괜찮습니다.
* '!' : 뭔가 주의가 필요한 메서드 뒤에는 '!'를 붙입니다.
* '?' : true/false를 반환하는 메서드 뒤에는 '?'를 붙입니다.
* '=' : 값을 할당하는 셋터 메서드 뒤에는 '='를 붙입니다.
=end
def plus_something(x, y=1) # 매개변수를 받을 수 있습니다. y에는 기본값을 줘봤습니다.
x + y # 'return'을 사용하지 않아도, 제일 마지막 문장의 값이 반환됩니다.
end
def get_something(*args) # 변수 이름 앞에 '*'을 붙여서 임의 길이의 매개변수를 전달 받을 수 있습니다.
puts "Hello"
end
def get_block(&block) # 변수 이름 앞에 '&'을 붙여서 블록을 전달 받을 수 있습니다.
block.call(self)
end
# 예외 처리
def my_method
begin
# 여기서 예외가 발생하면,
rescue
# 여기에서 예외를 처리합니다.
end
end
def my_method # 이렇게도 작성할 수 있습니다.
# 여기서 예외가 발생하면,
rescue
# 여기에서 예외를 처리합니다.
else
# 예외가 발생하지 않았을 때 처리할 내용
ensure
# 예외가 발생했든 말든 처리할 내용
end
# 메서드 호출
my_method()
my_method # 괄호는 없어도 됩니다.
my_method(x,y)
my_method x, y
array = [1,2,3]
my_method(*array) # my_method(1,2,3)과 같습니다.
hash = {a:1,b:2}
my_method(**hash) # 해시에는 '**'를 사용합니다.
my_method do # 메서드에 매개변수로 블록을 전달합니다.
# do something
end
my_method { # 메서드에 매개변수로 블록을 전달합니다.
# do something
}
a = [1,2,3]
b = ["a","b","c"]
c = a.append(*b).reverse # 메서드 호출을 연결
puts c
reg = /foo/
"Hello".match(reg)&.values_at(1,2) # '&'를 붙이면 결과가 nil일 때에 이후 메서드가 실행되지 않도록 합니다.
END{
# https://ruby-doc.org/3.2.2/syntax/methods_rdoc.html
# https://ruby-doc.org/3.2.2/syntax/calling_methods_rdoc.html
}

81
src/05_module.rb Executable file
View File

@@ -0,0 +1,81 @@
#!/usr/bin/ruby
# 모듈
module MyModule
def my_method
end
end
module MyModule # 같은 이름으로 여러 번 정의해도 하나의 모듈로 통합됩니다.
alias aliased_method my_method
end
module MyModule
remove_method :my_method
end
module OuterModule
module InnerModule
# 중첩도 됩니다.
end
end
module OuterModule::InnerModule::GrandsonModule
# 상위 모듈이 이미 정의되어 있는 경우에는, 이렇게 정의할 수도 있습니다.
end
# 클래스
class MyClass
# 클래스입니다.
end
class AnotherClass < MyClass
# MyClass를 상속하는 클래스입니다. 부모 클래스를 지정하지 않으면, 기본적으로 Object를 상속합니다.
# 뭔가 새로운 상속 구조를 만들려면, BasicObject를 상속합니다.
end
## 상속
class A
def value
@value
end
def value=(value)
@value = value
end
end
class B < A
def value
# super는 부모 클래스의 메서드에 현재 메서드의 매개변수를 전달해서 호출합니다.
# 전달할 매개변수 값을 지정하려면 super(1)와 같이 사용합니다.
1 + super
end
end
c = B.new
c.value = 1
puts c.value
## 싱글턴 패턴
class S
class << self
# ...
end
end
END{
# https://ruby-doc.org/3.2.2/syntax/modules_and_classes_rdoc.html
}

56
src/06_exception.rb Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/ruby
begin
# do something
rescue
# handle exception
end
# 메서드 내에서 예외를 처리하려는 경우,
def my_method
# do something
rescue
# handle exception
end
begin
# ...
rescue => exception # 예외를 지역 변수로 받습니다.
warn exception.message
raise # re-raise the current exception
end
begin
# ...
rescue ArgumentError # 예외를 종류 별로 처리할 수 있습니다.
# handle ArgumentError
rescue NameError
# handle NameError
rescue
# handle any StandardError
end
begin
# ...
rescue ArgumentError, NameError # 여러 종류의 예외를 묶어서 처리할 수도 있습니다.
# handle ArgumentError or NameError
end
begin
# ...
rescue
# ...
else
# this runs only when no exception was raised
ensure
# ...
end
END{
# https://ruby-doc.org/3.2.2/syntax/exceptions_rdoc.html
}

60
src/10_number.rb Executable file
View File

@@ -0,0 +1,60 @@
#!/usr/bin/ruby
## Numeric
## Integer
i = 3
p i.class # => Integer
p i.anybits?(0b00000000)
## Float
f = 3.141592
p f
## Rational
r = 1/3r
p r
puts "#{r.numerator} / #{r.denominator}"
## Complex
c = 10 + 3i
p c
puts "#{c.real} + #{c.imaginary}i"
## BigDecimal
require 'bigdecimal'
decimal = (BigDecimal("1.2") - BigDecimal("1.0"))
p decimal # 0.2e0
## Math
p Math::PI
p Math::E
p Math.sin(0.5)
p Math.log2(10)
END {
# https://ruby-doc.org/3.3.0/Numeric.html
# https://ruby-doc.org/3.3.0/Integer.html
# https://ruby-doc.org/3.3.0/Float.html
# https://ruby-doc.org/3.3.0/Rational.html
# https://ruby-doc.org/3.3.0/Complex.html
# https://ruby-doc.org/3.3.0/exts/bigdecimal/BigDecimal.html
# https://ruby-doc.org/3.3.0/Math.html
# https://ruby-doc.org/3.3.0/exts/bigdecimal/BigMath.html
# https://ruby-doc.org/3.3.0/gems/matrix/Matrix.html
# https://ruby-doc.org/3.3.0/gems/matrix/Vector.html
}

233
src/11_string.rb Executable file
View File

@@ -0,0 +1,233 @@
#!/usr/bin/ruby
# 문자열
## Substitution
s = "Hello, there"
str = s.sub(/[aeiou]/, '*') # 패턴과 일치하는 첫 번째 부분을 다른 문자열로 대체합니다.
str = s.gsub(/[aeiou]/, '*') # 패턴과 일치하는 모든 부분을 다른 문자열로 대체합니다.
puts str
## 공백 제거
str = s.strip
str = s.lstrip
str = s.rstrip
### 문자열을 배열처럼
str = "foo bar"
p str[0]
p str[0,3]
=begin
* length / size : 문자의 갯수
* bytesize
* empty?
* count : 일치하는 부분 문자열의 갯수를 반환
* index
* rindex
* include?
* match
* match?
* start_with?
* end_with?
* encoding
* unicode_normalized?
* valid_encoding?
* ascii_only?
* sum
* hash
* insert
* <<
* sub
* gsub
* succ
* next
* replace
* reverse
* setbyte
* tr
* tr_s
* dump
* undump
* capitalize
* downcase
* upcase
* swapcase
* encode
* unicode_normalize
* scrub
* force_encoding
* clear
* slice
* squeeze
* delete
* delete_prefix
* delete_suffix
* strip
* lstrip
* rstrip
* chomp
* chop
* chr
* byteslice
* center
* concat
* prepend
* ljust
* rjust
* to_s
* bytes
* chars
* getbyte
* lines
* partition
* rpartition
* split
* scan
* unpack
* hex
* oct
* to_i
* to_f
* each_byte
* each_char
* each_codepoint
* each_line
=end
## String IO
require 'stringio'
io = StringIO.new
io.close # 열었으면 닫아야 합니다.
StringIO.open {|io|
# do something
# 블록이 끝나면 클로즈됩니다.
}
str = <<STR
This is a text.
Hello, world!
The, bye.
STR
StringIO.open(str, 'r+'){|io|
io.each_line{|line|
puts "#{io.lineno}: #{line}"
}
}
=begin
* binmode
* close
* close_read
* close_write
* closed?
* closed_read?
* closed_write?
* eof?
* each
* each_byte
* each_char
* each_codepoint
* each_line
* getbyte
* getc
* gets
* length
* lineno
=end
## String Scanner
require 'strscan'
scanner = StringScanner.new('Hello world!')
p scanner.scan(/\w+/)
p scanner.scan(/\s+/)
p scanner.eos?
=begin
* getch
* get_byte
* scan
* scan_until
* skip
* skip_until
* check
* check_until
* exist?
* match?
* peek
* beginning_of_line?
* eos?
* rest?
* rest_size
* pos
* reset
* terminate
* matched
* matched?
* matched_size
* pre_match
* post_match
* unscan
=end
END{
# https://ruby-doc.org/3.3.0/String.html
# https://ruby-doc.org/3.3.0/exts/stringio/StringIO.html
# https://ruby-doc.org/3.3.0/exts/strscan/StringScanner.html
}

92
src/12_array.rb Executable file
View File

@@ -0,0 +1,92 @@
#!/usr/bin/ruby
# 배열
=begin
배열의 인덱스는 0부터 시작합니다.
인덱스가 음수인 경우에는 뒤에서부터 거꾸로 세는데,
-1이 가장 마지막 요소를 가리킵니다.
=end
# 배열의 생성
array = [1, "two", 3] # 배열의 리터럴을 사용해서 생성
array = Array(1..10) # 메서드를 사용한 생성
array = Array.new # 생성자를 통한 생성
# 배열의 요소에 접근하는 방법
array[0] = "A"
array[1] = "B"
array[3] = "D"
# 또는 메서드를 사용해서 접근
puts array.at(0)
puts array.first # 첫 번째 요소
puts array.last # 마지막 요소
array.take(3) # 배열의 맨 앞에서부터 3개로 이루어진 배열을 반환
array.drop(3)
puts array.length # 배열의 크기
puts array.count # 배열의 갯수
array.empty? # 빈 배열?
array.include?("Some Item") # 주어진 아이템이 배열에도 존재하는지 여부
# 배열에 추가
array.push("New item") # 배열의 맨 뒤에 아이템 추가
array << "Hello"
array.unshift("A") # 배열의 맨 앞에 아이템 추가
array.insert(3, "Orange", "Kiwi") # 원하는 인덱스에 아이템 추가
# 아이템 제거
array.pop # 배열에서 맨 끝 요소를 빼낸 다음 반환
array.shift # 배열의 맨 앞 아이템을 꺼내서 반환
array.delete_at(2) # 특정 인덱스의 아이템을 반환
array.delete("Orange")
array.compact # 배열에서 nil 값을 가진 아이템이 제거된 배열을 반환
array.compact! # 배열에서 nil 값을 가진 아이템을 제거한 다음 원래의 배열에 값을 할당.
# 반복
array.each{|item|
puts ${item}
}
array.reverse_each{|word|
str += "#{word}"
}
array.map {|i|
i*0.6
}
# 추출
array.select {
|a| a> 3
}
array.reject {
|a| a< 3
}
array.delete_if {
|a| a> 4
}
array.keep_if {
|a| a< 4
}
array.at(0)
array.first()
array.last()
array.min()
array.max()
array.take(3)
array.drop(3)
array.shuffle()
END{
# https://ruby-doc.org/3.3.0/Array.html
}

108
src/13_hash.rb Executable file
View File

@@ -0,0 +1,108 @@
#!/usr/bin/ruby
# 해시
## 해시 만들기
hash = {x: 100, y: 200}
person = {name: 'Charlie', age: 13}
hash = Hash.new
hash = Hash[]
hash = {}
hash = Hash[x: 100, y: 200]
## 아이템에 접근
hash[:x]
hash.delete(:x)
def my_method(hash)
p hash
end
my_method(hash)
my_method(x: 100, y: 200) # 괄호 없이도 해시를 매개변수로 전달할 수 있습니다.
=begin
* any?
* empty?
* has_value?
* include? / has_key? / menber? / key?
* length / size
* value?
=end
=begin
* assoc
* fetch
* fetch_values
* key
* keys
* values
* values_at
=end
=begin
* store
* merge
* update
* replace
* clear
* compact
* delete
* delete_if
* filter / select
* keep_if
* reject
* shift
* except
* slice
=end
=begin
* each
* each_pair
* each_key
* each_value
=end
=begin
* to_s
* to_a
* to_hash
* to_proc
=end
=begin
* flatten : 배열로 변환합니다.
* invert : 키/값을 서로 바꿉니다.
* transform_keys
* transform_values
=end
END{
# https://ruby-doc.org/3.3.0/Hash.html
}

38
src/14_range.rb Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/ruby
# 레인지
(1..4).to_a
(1...4).to_a
Range.new('a'..'d').to_a
=begin
* begin : 시작값
* count
* end
* exclude_end?
* first
* last
* max
* min
* minmax
* size
* include?
=end
=begin
* each
* step
=end
END{
# https://ruby-doc.org/3.3.0/Range.html
}

128
src/15_object.rb Executable file
View File

@@ -0,0 +1,128 @@
#!/usr/bin/ruby
# 객체
class Person
def initialize(first_name, last_name, age)
@first_name = first_name
@last_name = last_name
@age = age
end
def name
"#{@first_name} #{@last_name}"
end
end
steve = Person.new("Steve", "McQueen", 37)
puts steve.name
## Object
=begin
* kind_of?
* instance_of?
* instance_variable_defined?
* method
* methods
* nil?
* object_id
* private_methods
* protected_methods
* public_method
* public_methods
* singleton_class
* single_method
* singleton_methds
* define_singleton_method
* extend
* send
* public_send
* instance_variables
* remove_instance_variable
=end
=begin
* clone
* define_singleton_method
* display
* dup
* freeze
* itself
=end
## Struct
Customer = Struct.new("Customer", :name, :age, :address)
charlie = Customer.new('Charlie', 13, 'Seoul')
charlie.address = 'Busan'
p charlie.address
=begin
* to_h
* to_a
* to_s
* values
* each
* each_pair
=end
## Basic Object
class YetAnotherClass < BasicObject
end
## Singleton
require 'singleton'
class MyClass
include Singleton
def initialize
@something = 'unknown'
end
def something
@something
end
def something=(s)
@something = s
end
end
a = MyClass.instance
b = MyClass.instance
a.something = 'Awesome'
p b
END{
# https://ruby-doc.org/3.3.0/Object.html
# https://ruby-doc.org/3.3.0/Struct.html
# https://ruby-doc.org/3.3.0/stdlibs/ostruct/OpenStruct.html
# https://ruby-doc.org/3.3.0/BasicObject.html
# https://ruby-doc.org/3.3.0/stdlibs/singleton/Singleton.html
}

61
src/16_set.rb Executable file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/ruby
# Set
require 'set'
set1 = Set[1,2]
set1 = Set.new([1,2])
p set1
set2 = [1,2,3].to_set # 배열을 셋트로 변환
=begin
* length
* empty?
* include?
* subset?
* superset?
* disjoint?
* intersect?
=end
=begin
* add / add?
* merge
* replace
* clear
* delete / delete?
* subtract
* delete_if
* keep_if
* select
* reject
* | / union
* & / intersection
* - / difference
* ^
=end
=begin
* collect / map
* divide
* flatten
* join
* each
=end
END{
# https://ruby-doc.org/3.3.0/stdlibs/set/Set.html
}

151
src/17_time.rb Executable file
View File

@@ -0,0 +1,151 @@
#!/usr/bin/ruby
# 시간
## Time
### 시간 인스턴스 생성
now = Time.now
now = Time.new
date = Time.new(2021,11,22)
date = Time.new(2021,11,22,13,1,0, '+09:00') # 년, 월, 일, 시간대
date = Time.local(2021,11,22,13,1,0)
date = Time.utc(2021,11,22,13,1,0)
date = Time.at(0) # Epoch second
date = Time.at(now, in: '-04:00')
p date
### 인스턴스 메서드
another = now + 3600 # 초단위 숫자와 함께 '+'나 '-' 연산도 가능합니다.
=begin
* year
* month
* day / mday
* hour
* min
* sec
* usec : 마이크로 초
* nsec : 나노 초
* wday : 주에서 몇 번째 날인지. 일요일 == 0
* yday : 연에서 몇 번째 날인지. 1월 1일 == 1
* utc_offset : UTC 시간과 몇 초 차이가 나는지.
* to_f : Epoch 초
* to_i : Epoch 초
* to_r : Epoch 초
* zone : 타임존 문자열
=end
=begin
* utc?
* dst?
* sunday?
* monday?
* tuesday?
* wednesday?
* thursday?
* friday?
* saturday?
=end
=begin
* acstime : 문자열로 반환
* strftime : 문자열로 반환
* to_a : 배열 형식으로 반환
* to_s : 문자열로 반환
* getutc : 새로운 UTC 시간을 반환
* getlocal : 새로운 로컬 시간을 반환
* utc : UTC 시간으로 변환
* localtime : 로컬 시간으로 변환
* deconstruct_keys : 해시 형식으로 반환
=end
## Date
### 시간 인스턴스 생성
date = Date.new(2021,11,22)
date = Date.ordinal(2024,100) # 2024년의 100번째 날
date = Date.jd(2451083) # 줄리안 데이
date = Date.commercial(2024,24,5) # 2024년의 24번째 주, 5번째 날
date = Date.parse('2024-03-31')
date = Date.strptime('2024-03-31', '%Y-%m-%d')
### 클래스 메서드
=begin
* _httpdate
* _iso8061
* _rfc2822
* _rfc3339
* _xmlschema
* httpdate
* iso8061
* commercial
* jd
* gregorian_leap?
* julian_leap?
=end
### 인스턴스 메서드
=begin
* httpdate
* iso8061
* rfc2822
* rfc3339
* xmlschema
* year
* month
* day
* monday? ...
* next
* next_day
* next_month
* next_year
* prev_day
* prev_month
* prev_year
* to_datetime
* to_s
* to_time
=end
=begin
=end
=begin
=end
END{
# https://ruby-doc.org/3.3.0/Time.html
# https://ruby-doc.org/3.3.0/exts/date/Date.html
# https://ruby-doc.org/3.3.0/exts/date/DateTime.html
}

62
src/18_regexp.rb Executable file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/ruby
# 정규표현식
re = /red/ # 정규표현식은 '/'로 묶어서 표현합니다.
p re.match?('alfred') # 일치 여부만 확인할 경우
p re.match('alfred') # 일치 문자열 정보가 필요한 경우
'alfred'.match?(re) # 문자열의 메서드를 사용해도 됩니다.
i = (re =~ 'alfred') # '=~' 연산자를 사용하면 문자열에서 일치하는 위치의 인덱스를 반환합니다.
p i
## 글로벌 변수
=begin
* $~ : MatchData 객체
* $& : 일치하는 부분 문자열
* $` : 일치 하는 문자열의 앞 부분
* $' : 일치하는 문자열의 뒷 부분
* $+ : 그룹 매치
* $1, $2, .. : 일치하는 그룹
=end
## 클래스 메서드
=begin
* last_match
* timeout
* union
=end
## 인스턴스 메서드
=begin
* case_fold?
* fixed_encoding?
* match
* match?
* name_captures
* names
* options
* source
* timeout
* to_s
=end
END{
# https://ruby-doc.org/3.3.0/Regexp.html
}

45
src/19_random.rb Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/ruby
# 랜덤
## 클래스 메서드를 사용
r = Random.bytes(8) # 8바이트 길이의 랜덤 바이트
p r.size
r = Random.urandom(8) # 8바이트 길이의 랜덤 바이트
p r.size
r = Random.rand # 부동소수
p r
r = Random.rand(5) # 0부터 최대 값이 5 사이인 임의의 수
p r
r = Random.rand(1..6) # 범위 지정
p r
## 인스턴스 메서드를 사용할 수도 있습니다.
prng = Random.new
r = prng.bytes(8)
r = prng.rand(1..6)
## 시큐어 랜덤
require 'securerandom'
r = SecureRandom.rand # Random과 마찬가지 방식으로 사용할 수 있습니다.
r = Random.rand(1..6)
r = SecureRandom.alphanumeric(10) # 문자와 숫자로 구성된 랜덤 문자열
r = SecureRandom.hex(8) # 16진 문자열 형식으로
r = SecureRandom.base64(16) # babse64 형식의 랜덤 문자열
r = SecureRandom.urlsafe_base64(16)
r = SecureRandom.uuid # UUID
p r
END{
# https://ruby-doc.org/3.3.0/Random.html
# https://ruby-doc.org/3.3.0/stdlibs/securerandom/SecureRandom.html
}

263
src/21_file.rb Executable file
View File

@@ -0,0 +1,263 @@
#!/usr/bin/ruby
# 파일과 디렉토리
## File
file = File.new('sample.txt', File::RDWR | File::CREAT, 0644) # 읽기및쓰기 모드로 파일이없으면 생성하고, 퍼미션은 644.
file.write("Hello, there!")
file.close # 열었으면 닫아야죠
File.open('sample.txt', 'r'){|file|
p file.readline
}
File.write('sample2.txt', "Hahaha") # 이렇게도 쓰는 것도 가능합니다.
### 클래스 메서드
=begin
* link : 하드 링크를 생성합니다.
* symlink
* mkfifo
* absolute_path?
* absolute_path
* base_name
* dir_name
* expand_path
* ext_name
* fn_match?
* join
* path
* readlink
* realdirpath
* realpath
* split
* atime
* birthtime
* ctime
* mtime
* blockdev?
* chardev?
* directory?
* executable?
* executable_real?
* exist?
* file?
* ftype
* grpowned?
* identical?
* lstat
* owned?
* pipe?
* readable?
* readable_real?
*setgid?
* setuid?
* socket?
* stat
* sticky?
* symlink?
* umask
* world_readable?
* worls_writable?
* writable?
* writable_real?
* empty?
* size
* chmod
* chown
* lchmod
* lchown
* utime
* lutime
* rename
* flock
* truncate
* unlink
=end
### 인스턴스 메서드
=begin
* path
* atime
* birthtime
* ctime
* mtime
* lstat
* size
* truncate
=end
## Dir
dir = Dir.new('.')
p dir.read
p dir.read
dir.close
### 클래스 메서드
=begin
* chdir
* chroot
* children
* empty?
* entries
* exist?
* getwd : 'pwd'
* glob : 패턴에 일치하는 파일 패스를 배열로 반환
* home : 사용자 홈 디렉토리
* each_child : '.'과 '..'는 포함되지 않는다.
* for_each : '.'과 '..'도 포함
* mkdir
* open
* unlink / delete / rmdir
=end
### 인스턴스 메서드
=begin
* read
* close
* rewind
* seek
* pos
* children
* fileno : 정수 형태의 파일 디스크립터를 반환
* path
* tell
* each
* each_child
=end
## 임시 디렉토리
require 'tmpdir'
Dir.tmpdir #
Dir.mktmpdir{|dir|
puts "Location is #{Dir.tmpdir}/d"
}
## 임시 파일
require 'tempfile'
file = Tempfile.new('foo')
begin
# ...
ensure
file.close
file.unlink
end
Tempfile.create('foo') {|file|
# ...
}
## File Utils
FileUtils.pwd
=begin
* mkdir
* mkdirs
* link_entry
* link / ln
* symlink / ln_s
* remove_dir
* remove_entry
* remove_file
* remove / rm
* safe_unlink / rm_f
* rm_r
* rm_rf / rmtree
* rmdir
* pwd
* uptodate?
* chdir / ch
* chown
* chmod
* touch
* compare_file
* compare_stream
* copy_entry
* copy_file
* copy_stream
* copy / cp
* cp_r
* cp_rl
* install
* move / mv
=end
## Find
require 'find' # 주어진 디렉토리 및 자식 디렉토리를 탐색한다.
Find.find("#{ENV['HOME']}/Workspace") {|path|
if (File.directory?(path))
if File.basename(path).start_with?('.')
Find.prune # 더 깊이 들어가지 않는다.
else
next
end
else
puts path
end
}
END{
# https://ruby-doc.org/3.3.0/File.html
# https://ruby-doc.org/3.3.0/FileTest.html
# https://ruby-doc.org/3.3.0/Dir.html
# https://ruby-doc.org/3.3.0/stdlibs/tmpdir/Dir.html
# https://ruby-doc.org/3.3.0/stdlibs/tempfile/Tempfile.html
# https://ruby-doc.org/3.3.0/stdlibs/fileutils/FileUtils.html
# https://ruby-doc.org/3.3.0/stdlibs/find/Find.html
}

147
src/22_io.rb Executable file
View File

@@ -0,0 +1,147 @@
#!/usr/bin/ruby
# IO
## 클래스 메서드
=begin
* open
* pipe
* popen
* binread
* read
* readlines
* binwrite
* write
* foreach
=end
## 인스턴스 메서드
=begin
* getbyte
* getc
* gets
* pread
* read
* read_nonblock
* readbyte
* readchar
* readline
* readlines
* readpartial
=end
=begin
* <<
* print
* printf
* putc
* puts
* pwrite
* write
* write_nonblock
=end
=begin
* lineno
* pos
* reopen
* rewind
* seek
=end
=begin
* each / each_line
* each_byte
* each_char
* each_codepoint
=end
=begin
* fdatasync
* flush
* fsync
=end
###### ======================================
=begin
* read
* write
* tell
* pos
* seek
* rewind
* close
* cose_read
* close_write
* closed?
* eof?
=end
=begin
* each_line
* gets : 다음 한 줄 읽기
* readline : 다음 한 줄 읽기
* readlines : 모두 읽어서 배열로 반환
* lineno
=end
=begin
* getc
* readchar
* ungetc
* putc
* each_char
=end
=begin
* getbyte
* readbyte
* ungetbyte
* each_byte
=end
=begin
* each_codepoint
=end
END{
# https://ruby-doc.org/3.3.0/IO.html
# https://ruby-doc.org/3.3.0/exts/io/nonblock/IO.html
}

38
src/23_http.rb Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/ruby
# Http
## Open URI
require 'open-uri'
URI.open("https://www.naver.com") {|resp|
resp.each_line {|line|
p line
}
}
URI.open("https://www.naver.com", "User-Agent"=>"Ruby", "Authentication"=>"Bearer abcdef") {|resp|
resp.each_line {|line|
p line
}
}
uri = URI.parse("https://www.naver.com") #
uri.open {|resp|
# ...
}
END{
# https://ruby-doc.org/3.3.0/stdlibs/net/Net/HTTP.html
# https://ruby-doc.org/3.3.0/stdlibs/net/http/Net/HTTP.html
# https://ruby-doc.org/3.3.0/stdlibs/uri/URI.html
# https://ruby-doc.org/3.3.0/stdlibs/open-uri/OpenURI.html
}

51
src/24_kernel.rb Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/ruby
# 커널
=begin
* caller
* class
* frozen?
* global_variables
* local_variables
* test
=end
## IO
=begin
* gets
* open
* p
* print
* printf
* putc
* puts
* readline
* readlines
* select
=end
=begin
* eval
=end
a = eval "1 + 2" # 문자열을 스크립트 명령문으로 처리합니다.
p a # 3
END{
# https://ruby-doc.org/3.3.0/Kernel.html
# https://ruby-doc.org/3.3.0/ENV.html
}

108
src/25_process_thread.rb Executable file
View File

@@ -0,0 +1,108 @@
#!/usr/bin/ruby
# 프로세스와 스레드
## 프로세스
=begin
* gid : 그룹 아이디
* pid : 프로세스 아이디
* ppid : 부모 프로세스 아이디
* uid : 사용자 아이디
* abort : 현재 프로세스를 즉시 종료합니다.
* daemon : 프로세스를 백그라운드 프로세스로 전환시킵니다.
* at_exit
* exit : 프로세스를 종료시키고, SystemExit 예외를 던집니다.
* exit! : 프로세스를 즉시 종료시킵니다.
=end
exec('ls -al') # 현재 프로세스가 새로운 프로세스로 대체됩니다.
## 서브 프로세스
=begin
* detach : 자식 프로세스가 좀비 프로세스가 되지 않도록 합니다.
* fork : 자식 프로세스를 만듭니다.
* kill : 프로세스에 신호를 보냅니다.
* spawn : 자식 프로세스를 만듭니다.
* wait, waitpid : 자식 프로세스가 종료될 때까지 기다립니다.
* wait2, waitpid2
* waitall : 모든 자식 프로세스가 종료될 때까지 기다립니다.
=end
o = `ls -al` # 쉘 명령을 실행합니다. 표준 출력의 결과가 반환됩니다.
puts o
fork do # 현재 프로세스를 두 개로 나눕니다. 부모 프로세스는 wait()이나 detach()를 사용해야할 수도 있습니다.
# do something
end
pid = spawn('pwd') # 자식 프로세스를 만들고, 즉시 프로세스 아이디를 반환합니다.
system('pwd') # 자식 프로세스를 만들고, 실행 결과를 true/false/nil 중 하나로 반환합니다.
### Shellwords
require 'shellwords'
argv = Shellwords.split('one, two, three') # 문자열을 쉘 명령에 쓰기 좋은 형태의 배열로 쪼갭니다.
argv = 'one, two, three'.shellsplit
filename = Shellwords.escape("it's a file.txt") # 특수문자를 처리합니다.
filename = "it's a file.txt".shellescape
dir = "My Documents"
argv = %W[ls -lta -- #{dir}]
system(argv.shelljoin + " | less") # 배열을 문자열로 합칩니다.
## 스레드
thread = Thread.new {
# do something
"Job done."
}
thread.join # 스레드가 종료될 떄까지 메인 스레드를 멈춥니다.A
thread.value # 스레드의 마지막 값을 확인할 수 있습니다.
Thread.kill(thread) # 스레드를 종료시킵니다.
thread.exit
thread.status # 스레드의 동작 상태를 확인할 수 있습니다.
thread.alive?
thread.stop?
Thread.current # 현재 스레드를 반환합니다.
Thread.main
Thread.list
sleep(1.2) # 1.2초 동안 스레드를 대기시킵니다.
END{
# https://ruby-doc.org/3.3.0/Kernel.html
# https://ruby-doc.org/3.3.0/stdlibs/shellwords/Shellwords.html
# https://ruby-doc.org/3.3.0/Process.html
# https://ruby-doc.org/3.3.0/Thread.html
}

8
src/31_cgi.rb Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/ruby
END{
# https://ruby-doc.org/3.3.0/exts/cgi/CGI.html
# https://ruby-doc.org/3.3.0/stdlibs/cgi/CGI.html
}

9
src/32_security.rb Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/ruby
END{
# https://ruby-doc.org/3.3.0/exts/digest/Digest.html
# https://ruby-doc.org/3.3.0/exts/openssl/OpenSSL.html
# https://ruby-doc.org/3.3.0/stdlibs/securerandom/SecureRandom.html
}

45
src/33_logger.rb Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/ruby
# 로깅
require 'logger'
## 로거 인스턴스 만들기
logger = Logger.new('my.log')
logger = Logger.new('my.log', 3, 10485760) # 각 10메가바이트 크기로 3개의 파일만
logger = Logger.new('my.log', 'daily') # daily | weekly | monthly
logger = Logger.new($stdout)
## 로깅
logger.add(Logger::DEBUG, 'Maximal debugging info') # add 메서드로 로깅을 합니다.
logger.add(Logger::INFO, 'Non-error information')
logger.add(Logger::WARN, 'Non-error warning')
logger.add(Logger::ERROR, 'Non-fatal error')
logger.add(Logger::FATAL, 'Fatal error')
logger.add(Logger::UNKNOWN, 'Most severe')
logger.debug('Maximal debugging info') # 좀 더 짧게 사용할 수 있습니다.
logger.info('Non-error information')
logger.warn('Non-error warning')
logger.error('Non-fatal error')
logger.fatal('Fatal error')
logger.unknown('Most severe')
## 닫기
logger.close # 사용이 끝나면 닫아줍니다.
END{
# https://ruby-doc.org/3.3.0/stdlibs/logger/Logger.html
}

13
src/34_socket.rb Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/ruby
END{
# https://ruby-doc.org/3.3.0/exts/socket/Socket.html
# https://ruby-doc.org/3.3.0/exts/socket/TCPServer.html
# https://ruby-doc.org/3.3.0/exts/socket/TCPSocket.html
# https://ruby-doc.org/3.3.0/exts/socket/UDPSocket.html
# https://ruby-doc.org/3.3.0/stdlibs/ipaddr/IPAddr.html
# https://ruby-doc.org/3.3.0/stdlibs/ipaddr/IPSocket.html
}

7
src/35_compress.rb Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/ruby
END{
# https://ruby-doc.org/3.3.0/exts/zlib/Zlib.html
}

22
src/36_base64.rb Executable file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/ruby
require 'base64'
encoded = Base64.encode64('Hello, World!') # "SGVsbG8sIFdvcmxkIQ==\n" 각 60문자마다, 그리고 맨 뒤에 줄바꿈 문자가 추가됩니다.
decodeed = Base64.decode64(encoded)
encoded = Base64.urlsafe_encode64('Hello, World!') # "SGVsbG8sIFdvcmxkIQ=="
decodeed = Base64.urlsafe_decode64(encoded)
encoded = Base64.strict_encode64('Hello, World!') # "SGVsbG8sIFdvcmxkIQ==" 줄바꿈이 추가되지 않습니다.
decodeed = Base64.strict_decode64(encoded)
p encoded
p decodeed
END{
# https://ruby-doc.org/3.3.0/stdlibs/base64/Base64.html
}

29
src/37_json.rb Executable file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/ruby
# JSON
require 'json'
## 읽기
json = '{"name":"Charlie", "age":14, "human":true}'
data = JSON.parse(json);
p data # {"name"=>"Charlie", "age"=>14, "human"=>true}
data = JSON.parse(File.read('sample.json')) # 파일로부터 읽어 오기
p data
## 내보내기
hash = {name:"Charlie", age: 13, alien:false}
json_str = JSON.generate(hash)
p json_str
array = [0, 's', true, hash]
json_str = JSON.generate(array)
p json_str
END{
# https://ruby-doc.org/3.3.0/exts/json/JSON.html
}

98
src/38_csv.rb Executable file
View File

@@ -0,0 +1,98 @@
#!/usr/bin/ruby
# Comma Separated Value
require 'csv'
## 읽기
csv = <<CSV
Charlie, 13
Steve, 43
Jane, 27
CSV
data = CSV.parse(csv)
p data # [["Charlie", " 13"], ["Steve", " 43"], ["Jane", " 27"]]
data = CSV.parse_line(csv) # 맨 첫 줄만 읽습니다.
p csv.parse_csv # 문자열에도 메서드가 추가되었습니다만, 첫 줄만 읽습니다.
data = CSV.read('sample.csv') # 파일에서 바로 읽어 올 수도 있아요.
CSV.foreach('sample.csv') do |row|
p row # 각 행마다 반복적으로 블록을 통해 처리할 수도 있어요.
end
## 헤더와 함께 읽기
csv_with_header = <<CSV
Name, Age
Charlie, 13
Steve, 43
Jane, 27
CSV
data = CSV.parse(csv_with_header, headers: true)
p data.headers
data.each do |row|
p row.to_h
end
## 내보내기
string = CSV.generate() do |csv|
csv << ['Name', 'Age']
csv << ['Charlie', 13]
csv << ['Steve', 43]
csv << ['Jane', 27]
end
p string
## 인스턴스 메서드
csv = <<CSV
Name, Age
Charlie, 13
Steve, 43
Jane, 27
CSV
parser = CSV.new(csv, headers: true)
p parser
p parser.shift.to_h
## 옵션
DEFAULT_OPTIONS = {
# For both parsing and generating.
col_sep: ",",
row_sep: :auto,
quote_char: '"',
# For parsing.
field_size_limit: nil,
converters: nil,
unconverted_fields: nil,
headers: false,
return_headers: false,
header_converters: nil,
skip_blanks: false,
skip_lines: nil,
liberal_parsing: false,
nil_value: nil,
empty_value: "",
strip: false,
# For generating.
write_headers: nil,
quote_empty: true,
force_quotes: false,
write_converters: nil,
write_nil_value: nil,
write_empty_value: "",
}
END{
# https://ruby-doc.org/3.3.0/stdlibs/csv/CSV.html
}

35
src/39_yaml.rb Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/ruby
# YAML
require 'yaml'
## 읽기
yaml = <<YAML
foo: bar
bar:
- foo
- bar
YAML
data = YAML.load(yaml)
p data # {"foo"=>"bar", "bar"=>["foo", "bar"]}
data = YAML.load_file('sample.yaml')
p data
## 내보내기
hash = {foo: 'bar', bar:['foo', 'bar']}
str = YAML.dump(hash) # 해시 등의 객체를 dump()하면 yaml 문자열이 나옵니다.
p str # "---\n:foo: bar\n:bar:\n- foo\n- bar\n"
str = hash.to_yaml # 또는, 해시나 배열 등에서 to_yaml 메서드를 호출
p str # "---\n:foo: bar\n:bar:\n- foo\n- bar\n"
END{
# https://ruby-doc.org/3.3.0/stdlibs/yaml/YAML.html
}

12
src/41_dbi.rb Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/ruby
=begin
=end
END{
# https://www.tutorialspoint.com/ruby/ruby_database_access.htm
# https://www.devdungeon.com/content/ruby-activerecord-without-rails-tutorial
}

49
src/data_type.rb Executable file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/ruby
=begin
This is a comment.
=end
# Number
i = 34
f = 3.14
# Stirng
s = "Hello"
doc = <<EOL # Here doc
This is
a text.
EOL
puts doc
# Array
a = ["A", "B", "C"]
a.each do |i|
puts "Item = #{i}"
end
# Hash
h = {
"A" => 1,
"B" => 2,
"C" => 3
}
h.each do |key,value|
puts "#{key} => #{value}"
end
# Range
(2..5).each do |i| #inclusive
puts "#{i}"
end
(2...5).each do |i| #exclusive
puts "#{i}"
end
BEGIN{
puts "Begining..."
}
END {
puts "Finished."
}

1
src/my.log Normal file
View File

@@ -0,0 +1 @@
# Logfile created on 2024-04-01 05:53:45 +0900 by logger.rb/v1.4.3

3
src/sample.csv Normal file
View File

@@ -0,0 +1,3 @@
Charlie, 13
Steve, 43
Jane, 27
1 Charlie 13
2 Steve 43
3 Jane 27

1
src/sample.json Normal file
View File

@@ -0,0 +1 @@
{"name":"Charlie", "age":14, "human":true}

1
src/sample.txt Normal file
View File

@@ -0,0 +1 @@
Hello, there!

4
src/sample.yaml Normal file
View File

@@ -0,0 +1,4 @@
foo: bar
bar:
- foo
- bar

1
src/sample2.txt Normal file
View File

@@ -0,0 +1 @@
Hahaha