Rust “Hello World!” in three languages

2023-01-08 21:26:51 +0000

For our first program, we want to write something that outputs the following text in multiple languages: Hello, world! Grüß Gott! ハロー・ワールド You have probably seen the first line. The other two are there to highlight a few of Rust’s features: easy iteration and built-in support for Unicode.

fn greet_world() { 
  println!("Hello World");
  let southern_germany = "Grüß Gott!";
  let japan = "ハロー・ワールド";
  let regions = [southern_germany, japan];
  for region in regions.iter() { 
    println!("{}", &region);
  }
}

fn main() { 
  greet_world();
}

Now that src/main.rs is updated, execute cargo run from the hello2/ directory. You should see three greetings appear after some output generated from cargo itself:

$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.95s
Running `target/debug/hello-world`
Hello, world!
Grüß Gott!
ハロー・ワールド

Let’s take a few moments to touch on some of the interesting elements of Rust from One of the first things that you are likely to notice is that strings in Rust are able to include a wide range of characters. Strings are guaranteed to be encoded as UTF-8. This means that you can use non-English languages with relative ease. The one character that might look out of place is the exclamation mark after println. If you have programmed in Ruby, you may be used to thinking that it is used to signal a destructive operation. In Rust, it signals the use of a macro. Macros can be thought of as fancy functions for now. These offer the ability to avoid boilerplate code. In the case of println!, there is a lot of type detection going on under the hood so that arbitrary data types can be printed to the screen.

Ruby method missing

2023-01-05 23:54:32 +0000

Method_missing is one of those special sauces that make Ruby such a wonderful programming language. It acts like a catch-all method in a class - if you call a method that the class doesn’t know how to respond to, Ruby will first look for a method_missing method to handle this unexpected method call. If method_missing doesn’t exist, then the typical NoMethodError will be raised. With method_missing, you can truly create dynamic classes that respond to a wide variety of methods, based on things like database fields - Active Record uses method_missing extensively to define getter and setter methods for each of the fields in the model’s database table. For an contrived example of method_missing in the flesh, you could define a class like the following:

class StringLength
   def method_missing(arg)
       "'#{arg}' has #{arg.length} letters!"
     end
end

And then interact with your class like so:

> StringLength.new.a_word
=> "'a_word' has 6 letters!"
> StringLength.new.something_long
=> "'something_long' has 14 letters!"
> StringLength.new.does_it_respond_to_anything?
=> "'does_it_respond_to_anything?' has 28 letters!"

You probably won’t use method_missing extensively in your Rails apps, but it’s good to know it exists, and the kinds of dynamic interfaces it can create.

Elixir - Maps

2021-11-10 18:16:18 +0000

Maps

Whenever you need a key-value store, maps are the “go to” data structure in Elixir. A map is created using the %{} syntax:

iex> map = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> map[:a]
1
iex> map[2]
:b
iex> map[:c]
nil

Compared to keyword lists, we can already see two differences:

  • Maps allow any value as a key.
  • Maps’ keys do not follow any ordering.

In contrast to keyword lists, maps are very useful with pattern matching. When a map is used in a pattern, it will always match on a subset of the given value:

iex> %{} = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> %{:a => a} = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> a
1
iex> %{:c => c} = %{:a => 1, 2 => :b}
** (MatchError) no match of right hand side value: %{2 => :b, :a => 1}

As shown above, a map matches as long as the keys in the pattern exist in the given map. Therefore, an empty map matches all maps.

Variables can be used when accessing, matching and adding map keys:

iex> n = 1
1
iex> map = %{n => :one}
%{1 => :one}
iex> map[n]
:one
iex> %{^n => :one} = %{1 => :one, 2 => :two, 3 => :three}
%{1 => :one, 2 => :two, 3 => :three}

The Map module provides a very similar API to the Keyword module with convenience functions to manipulate maps:

iex> Map.get(%{:a => 1, 2 => :b}, :a)
1
iex> Map.put(%{:a => 1, 2 => :b}, :c, 3)
%{2 => :b, :a => 1, :c => 3}
iex> Map.to_list(%{:a => 1, 2 => :b})
[{2, :b}, {:a, 1}]

Maps have the following syntax for updating a key’s value:

iex> map = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}

iex> %{map | 2 => "two"}
%{2 => "two", :a => 1}
iex> %{map | :c => 3}
** (KeyError) key :c not found in: %{2 => :b, :a => 1}

The syntax above requires the given key to exist. It cannot be used to add new keys. For example, using it with the :c key failed because there is no :c in the map.

When all the keys in a map are atoms, you can use the keyword syntax for convenience:

iex> map = %{a: 1, b: 2}
%{a: 1, b: 2}

Another interesting property of maps is that they provide their own syntax for accessing atom keys:

iex> map = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}

iex> map.a
1
iex> map.c
** (KeyError) key :c not found in: %{2 => :b, :a => 1}

Elixir developers typically prefer to use the map.field syntax and pattern matching instead of the functions in the Map module when working with maps because they lead to an assertive style of programming. This blog post by José Valim provides insight and examples on how you get more concise and faster software by writing assertive code in Elixir.

Nested data structures

Often we will have maps inside maps, or even keywords lists inside maps, and so forth. Elixir provides conveniences for manipulating nested data structures via the put_in/2 , update_in/2 and other macros giving the same conveniences you would find in imperative languages while keeping the immutable properties of the language.

Imagine you have the following structure:

iex> users = [
  john: %{name: "John", age: 27, languages: ["Erlang", "Ruby", "Elixir"]},
  mary: %{name: "Mary", age: 29, languages: ["Elixir", "F#", "Clojure"]}
]
[
  john: %{age: 27, languages: ["Erlang", "Ruby", "Elixir"], name: "John"},
  mary: %{age: 29, languages: ["Elixir", "F#", "Clojure"], name: "Mary"}
]

We have a keyword list of users where each value is a map containing the name, age and a list of programming languages each user likes. If we wanted to access the age for john, we could write:

iex> users[:john].age
27

It happens we can also use this same syntax for updating the value:

iex> users = put_in users[:john].age, 31
[
  john: %{age: 31, languages: ["Erlang", "Ruby", "Elixir"], name: "John"},
  mary: %{age: 29, languages: ["Elixir", "F#", "Clojure"], name: "Mary"}
]

The update_in/2 macro is similar but allows us to pass a function that controls how the value changes. For example, let’s remove “Clojure” from Mary’s list of languages:

iex> users = update_in users[:mary].languages, fn languages -> List.delete(languages, "Clojure") end
[
  john: %{age: 31, languages: ["Erlang", "Ruby", "Elixir"], name: "John"},
  mary: %{age: 29, languages: ["Elixir", "F#"], name: "Mary"}
]

There is more to learn about put_in/2 and update_in/2, including the get_and_update_in/2 that allows us to extract a value and update the data structure at once. There are also put_in/3, update_in/3 and get_and_update_in/3 which allow dynamic access into the data structure.

This concludes our introduction to associative data structures in Elixir. You will find out that, given keyword lists and maps, you will always have the right tool to tackle problems that require associative data structures in Elixir.

Ruby Equality tests

2021-10-31 19:21:59 +0000

The Object class defines three equality-test methods: ==, eql?, and equal?. At the Object level, all equality-test methods do the same thing: they tell you whether two objects are exactly the same object. Here they are in action:

>> a = Object.new
=> #<Object:0x00000101258af8>
>> b = Object.new
=> #<Object:0x00000101251d70>
>> a == a
=> true
>> a == b
=> false
>> a != b
=> true
>> a.eql?(a)
=> true
>> a.eql?(b)
=> false
>> a.equal?(a)
=> true
>> a.equal?(b)
=> false

All three of the positive equality-test methods give the same results in these examples: when you test a against a, the result is true, and when you test a against b, the result is false. (The not-equal or negative equality test method != is the inverse of the == method; in fact, if you define ==, your objects will automatically have the != method.) We have plenty of ways to establish that a is a but not b.

But there isn’t much point in having three tests that do the same thing.

Further down the road, in classes other than Object, == and/or eql? are typically redefined to do meaningful work for different objects. For example, String redefines == and eql? to return whether the value of the strings being compared are identical. Two strings can have the same value but in fact be different objects. The equal? method retains its Object definition and checks if two strings are exactly the same object. Let’s look at string equality in action:

>> string1 = "text"
=> "text"
>> string2 = "text"
=> "text"
>> string1 == string2
=> true
>> string1.eql?(string2)
=> true
>> string1.equal?(string2)
=> false

As you can see, the strings are == and eql?, but not equal?. Ruby recommends against redefining equal? so that it can always be used to determine object identity.

Why do we have == and eql? if they’re synonymous at the Object level? Because it gives us more flexibility as we subclass Object. Because we don’t redefine equal?, we have the option to redefine either == or eql? and compare objects in different ways.

For example, in the Numeric class (a superclass of Integer and Float), == performs type conversion before making a comparison but eql? doesn’t:

>> 5 == 5.0
=> true
>> 5.eql? 5.0
=> false

Ruby gives you a suite of tools for object comparisons, and not always just comparison for equality.

Ruby remember a method name

2021-10-31 01:19:49 +0000

Trying to remember a method name or just discover what you can call on an object? Ruby has you covered! Check out examples below

List all methods

User.methods

List all direct methods except Object class methods

User.methods - Object.methods

List all direct methods ( not comming from a parent class )

User.methods(false)

List all instance methods

User.instance_methods

List all direct instance methods

User.instance_methods(false)

List all methods and then grep on them

User.methods.grep(/find/)
=> [:find_for_database_authentication,
 :find_for_authentication,
 :find_first_by_auth_conditions,
 :find_or_initialize_with_error_by,
 :find_or_initialize_with_errors,
 :_find_callbacks,
 :_find_callbacks=,
 :after_find,
 :finder_needs_type_condition?,
 :find_by!,
 :cached_find_by_statement,
 :find_by,
 :initialize_find_by_cache,
 :find,
 :find_or_create_by,
 :find_or_create_by!,
 :find_or_initialize_by,
 :create_or_find_by,
 :create_or_find_by!,
 :find_each,
 :find_in_batches,
 :find_by_sql]



subscribe via RSS