Skip to content

Commit

Permalink
added 2024-12-22-paradox-of-choice.md
Browse files Browse the repository at this point in the history
  • Loading branch information
halyph committed Dec 22, 2024
1 parent 78893cc commit ca7807b
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ _Another attempt of blogging or personal knowledge base_

## 2024

- 2024-12-22 - [Paradox of Choice in Ruby](docs/blog/2024/2024-12-22-paradox-of-choice.md)
- 2024-12-01 - [Languages popularity by SDKs](docs/blog/2024/2024-12-01-lang-pop-by-sdk.md)
- 2024-08-14 - [Everybody Python, FTW?](docs/blog/2024/2024-08-14-rant-python.md)

Expand Down
296 changes: 296 additions & 0 deletions docs/blog/2024/2024-12-22-paradox-of-choice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
# Paradox of Choice in Ruby
> | ruby |
[The Paradox of Choice – Why More Is Less](https://en.wikipedia.org/wiki/The_Paradox_of_Choice) - is it applicable to programming languages?

I've been using simple (in terms of syntax) languages (*Python*,*Go*) for some time and have an understanding of why such fancy, flexible language as *Ruby* has sort of "irritation" from some software engineers.

*Please note*, that I am talking about language only, avoiding ecosystem, Rails, and so on.

Ruby is too flexible. It has too many ways of doing the same things using different methods. And after Python/Go it is a big deal for me. I want to concentrate on simple code, which I can read and understand quickly. Yes, I want to see elegant code as well, but today it's more important for me to follow a "less is more" approach, with few possible variations.

Based on my subjective experience, Ruby is very close to Perl. I don't understand why they haven't deprecated some legacy in Ruby. It would make the language cleaner and remove ambiguity.

## Samples of "More is More" in Ruby language

I decided to collect basic samples of doing the same/similar things in Ruby, ignoring meta-programming. It's not exhaustive list of "questionable" features. I am too lazy to write really long post, but it should give you of a feeling of what I mean.

### Loading Code

- `require`: Loads a library or file once. Commonly used for loading gems or external libraries.
- `require_relative`: Similar to `require`, but resolves file paths relative to the file making the call.
- `load`: Loads and re-evaluates the code in a file every time it’s called.
- `autoload`: Registers the given file to be loaded when the given constant is first referenced.

### Mixing In Modules

- `include`: Mixes module methods as instance methods into a class.
- `extend`: Adds module methods as class methods or singleton methods.
- `prepend`: Similar to include, but methods are added to the top of the method lookup chain, overriding existing methods.


### Array

```ruby
array = [1, 2, 3, 4]
```

#### Using `%w` for Strings

To create an array of strings without quotes and commas:

```ruby
array = %w[apple banana cherry]
# => ["apple", "banana", "cherry"]
```
For strings with interpolation or escape sequences, use `%W`:

```ruby
name = "John"
array = %W[hello #{name} world]
# => ["hello", "John", "world"]
```

#### Using `%i` for Symbols

To create an array of symbols:

```ruby
array = %i[one two three]
# => [:one, :two, :three]
```

#### Using `Array()` Method

The Array() method can convert other types to arrays.

```ruby
array = Array(1..5)
# => [1, 2, 3, 4, 5]
```

### String

#### Alternative to single `'` and double-quote `"` delimiters

Ruby provides an alternative to single and double-quote delimiters, which comes in handy
sometimes when the string you want to quote contains the delimiter you need.

You can use various delimiters with `%Q`. The most common are `[ ]`, `{ }`, `( )`, `| |`, or `/ /`. The opening and closing delimiters must match.

```ruby
%q/general single-quoted string/ # => general single-quoted string
%Q!general double-quoted string! # => general double-quoted string
%Q{Seconds/day: #{24*60*60}} # => Seconds/day: 86400
%!general double-quoted string! # => general double-quoted string
%{Seconds/day: #{24*60*60}} # => Seconds/day: 86400
```

#### Here document (or heredoc)

A heredoc allows you to build a multi-line string.

```ruby
string = <<END_OF_STRING
The body of the string is the input lines up to
one starting with the same text that followed the '<<'
END_OF_STRING
```

```ruby
string = <<-END_OF_STRING
The body of the string is the input lines up to
one starting with the same text that followed the '<<'
END_OF_STRING
```

And if you put a tilde after the << characters you can indent the text.

```ruby
def a_long_string
<<~END_OF_STRING
Faster than a speeding bullet, more powerful than
a locomotive, able to leap tall buildings in a single
bound—look, up there in the sky, it's a bird, it's a
plane, it's Superman!
END_OF_STRING
end
puts a_long_string
```

You can also have multiple here documents on a single line

```ruby
print <<-STRING1, <<-STRING2
Concat
STRING1
enate
STRING2

# produces:
# Concat
# enate
```

### Hash

```ruby
{ :one => "eins", :two => "zwei", :three => "drei" }
```

Using this syntax we tell Ruby that we want the keys to be symbols.

```ruby
{ one: "eins", two: "zwei", three: "drei" }
```

## Conditional Statements `if` vs `unless`

Executes code if the condition is `false`.

```ruby
unless x >= 0
puts "x is negative"
else
puts "x is non-negative"
end
```

```ruby
puts "x is negative" unless x >= 0
```

## Loops

#### `loop`

```ruby
i = 1

loop do
puts "Message number #{i}"

i = i + 1
if i == 6
break
end
end
```

#### `while`

```ruby
i = 1

while i <= 5 do
puts "Message number #{i}"
i = i + 1
end
```

#### `for`

```ruby
for i in 1..5 do
puts "Message number #{i}"
end
```

#### `until`

```ruby
i = 1

until i == 6 do
puts "Message number #{i}"
i = i + 1
end
```

#### `begin` ... `end` block

```ruby
print "Hello\n" while false
begin
print "Goodbye\n"
end while false

# produces:
# Goodbye
```

### Aliases

#### `length` / `size`: Return the number of elements in the array

```ruby
arr = [1, 2, 3]
arr.length # => 3
arr.size # => 3
```

#### `map` / `collect`: Create a new array by applying a block to each element

```ruby
arr = [1, 2, 3]
arr.map { |x| x * 2 } # => [2, 4, 6]
arr.collect { |x| x * 2 } # => [2, 4, 6]
```

#### `reduce` / `inject`: Combine all elements of the array by applying a binary operation

```ruby
arr = [1, 2, 3]
arr.reduce(:+) # => 6
arr.inject(:+) # => 6
```

#### `find` / `detect`: Return the first element that satisfies the block

```ruby
arr = [1, 2, 3, 4]
arr.find { |x| x > 2 } # => 3
arr.detect { |x| x > 2 } # => 3
```

#### `select` / `find_all` / `filter`: Return all elements that satisfy the block

```ruby
arr = [1, 2, 3, 4]
arr.select { |x| x.even? } # => [2, 4]
arr.find_all { |x| x.even? } # => [2, 4]
```

#### key? / has_key?: Check if a key exists in the hash

```ruby
hash = { a: 1, b: 2 }
hash.key?(:a) # => true
hash.has_key?(:a) # => true
```

#### `reject` / `delete_if`: Return elements that do not satisfy the block

```ruby
arr = [1, 2, 3, 4]
arr.reject { |x| x.even? } # => [1, 3]
arr.delete_if { |x| x.even? } # => [1, 3]
```

#### `exists?` / `exist?`: Check if a file exists

```ruby
File.exists?("file.txt") # => true or false
File.exist?("file.txt") # => true or false
```
#### `size` / `size?`

- `size`: Returns the size of the file in bytes.
- `size?`: Returns the size if the file is non-empty; otherwise, returns nil.

```ruby
File.size("file.txt") # => 1024
File.size?("file.txt") # => 1024 or nil
```

There are more similar cases, but you've got what I mean 😉, right?
1 change: 1 addition & 0 deletions docs/blog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ hide:

## 2024

- 2024-12-22 - [Paradox of Choice in Ruby](2024/2024-12-22-paradox-of-choice.md)
- 2024-12-01 - [Languages popularity by SDKs](2024/2024-12-01-lang-pop-by-sdk.md)
- 2024-08-14 - [Everybody Python, FTW?](2024/2024-08-14-rant-python.md)

Expand Down

0 comments on commit ca7807b

Please sign in to comment.