Go Errors

2021-10-29 00:19:13 +0000

In Go it’s idiomatic to communicate errors via an explicit, separate return value. This contrasts with the exceptions used in languages like Java and Ruby and the overloaded single result / error value sometimes used in C. Go’s approach makes it easy to see which functions return errors and to handle them using the same language constructs employed for any other, non-error tasks

By convention, errors are the last return value and have type error, a built-in interface.

errors.New constructs a basic error value with the given error message.

A nil value in the error position indicates that there was no error.

It’s possible to use custom types as errors by implementing the Error() method on them. Here’s a variant on the example above that uses a custom type to explicitly represent an argument error.

In this case we use &argError syntax to build a new struct, supplying values for the two fields arg and prob.

The two loops below test out each of our error-returning functions. Note that the use of an inline error check on the if line is a common idiom in Go code.

If you want to programmatically use the data in a custom error, you’ll need to get the error as an instance of the custom error type via type assertion.

package main

import (
    "errors"
    "fmt"
)

func f1(arg int) (int, error) {
    if arg == 42 {

        return -1, errors.New("can't work with 42")

    }

    return arg + 3, nil
}

type argError struct {
    arg  int
    prob string
}

func (e *argError) Error() string {
    return fmt.Sprintf("%d - %s", e.arg, e.prob)
}

func f2(arg int) (int, error) {
    if arg == 42 {

        return -1, &argError{arg, "can't work with it"}
    }
    return arg + 3, nil
}

func main() {

    for _, i := range []int{7, 42} {
        if r, e := f1(i); e != nil {
            fmt.Println("f1 failed:", e)
        } else {
            fmt.Println("f1 worked:", r)
        }
    }
    for _, i := range []int{7, 42} {
        if r, e := f2(i); e != nil {
            fmt.Println("f2 failed:", e)
        } else {
            fmt.Println("f2 worked:", r)
        }
    }

    _, e := f2(42)
    if ae, ok := e.(*argError); ok {
        fmt.Println(ae.arg)
        fmt.Println(ae.prob)
    }
}
$ go run errors.go
f1 worked: 10
f1 failed: can't work with 42
f2 worked: 10
f2 failed: 42 - can't work with it
42
can't work with it

See this great post on the Go blog for more on error handling.

What is Proc in Ruby

2021-09-20 20:39:07 +0000

A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another Proc, and can be called. Proc is an essential concept in Ruby and a core of its functional programming features.

square = Proc.new {|x| x**2 }

square.call(3)  #=> 9
# shorthands:
square.(3)      #=> 9
square[3]       #=> 9

Proc objects are closures, meaning they remember and can use the entire context in which they were created.

def gen_times(factor)
  Proc.new {|n| n*factor } # remembers the value of factor at the moment of creation
end

times3 = gen_times(3)
times5 = gen_times(5)

times3.call(12)               #=> 36
times5.call(5)                #=> 25
times3.call(times5.call(4))   #=> 60

Creation

There are several methods to create a Proc

  • Use the Proc class constructor:
proc1 = Proc.new {|x| x**2 }
  • Use the Kernel#proc method as a shorthand of ::new:
proc2 = proc {|x| x**2 }
  • Receiving a block of code into proc argument (note the &):
def make_proc(&block)
  block
end

proc3 = make_proc {|x| x**2 }
  • Construct a proc with lambda semantics using the Kernel#lambda method (see below for explanations about lambdas):
lambda1 = lambda {|x| x**2 }

*Use the Lambda literal syntax (also constructs a proc with lambda semantics):

lambda2 = ->(x) { x**2 }

Lambda and non-lambda semantics

  • Procs are coming in two flavors: lambda and non-lambda (regular procs). Differences are:
  • In lambdas, return means exit from this lambda;

*In regular procs, return means exit from embracing method (and will throw LocalJumpError if invoked outside the method);

*In lambdas, arguments are treated in the same way as in methods: strict, with ArgumentError for mismatching argument number, and no additional argument processing;

*Regular procs accept arguments more generously: missing arguments are filled with nil, single Array arguments are deconstructed if the proc has multiple arguments, and there is no error raised on extra arguments

p = proc {|x, y| "x=#{x}, y=#{y}" }
p.call(1, 2)      #=> "x=1, y=2"
p.call([1, 2])    #=> "x=1, y=2", array deconstructed
p.call(1, 2, 8)   #=> "x=1, y=2", extra argument discarded
p.call(1)         #=> "x=1, y=", nil substituted instead of error

l = lambda {|x, y| "x=#{x}, y=#{y}" }
l.call(1, 2)      #=> "x=1, y=2"
l.call([1, 2])    # ArgumentError: wrong number of arguments (given 1, expected 2)
l.call(1, 2, 8)   # ArgumentError: wrong number of arguments (given 3, expected 2)
l.call(1)         # ArgumentError: wrong number of arguments (given 1, expected 2)

def test_return
  -> { return 3 }.call      # just returns from lambda into method body
  proc { return 4 }.call    # returns from method
  return 5
end

test_return # => 4, return from proc

Lambdas are useful as self-sufficient functions, in particular useful as arguments to higher-order functions, behaving exactly like Ruby methods.

Procs are useful for implementing iterators:

def test
  [[1, 2], [3, 4], [5, 6]].map {|a, b| return a if a + b > 10 }
                            #  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
end

Inside map, the block of code is treated as a regular (non-lambda) proc, which means that the internal arrays will be deconstructed to pairs of arguments, and return will exit from the method test. That would not be possible with a stricter lambda.

You can tell a lambda from a regular proc by using the lambda? instance method.

Lambda semantics is typically preserved during the proc lifetime, including &-deconstruction to a block of code:

p = proc {|x, y| x }
l = lambda {|x, y| x }
[[1, 2], [3, 4]].map(&p) #=> [1, 2]
[[1, 2], [3, 4]].map(&l) # ArgumentError: wrong number of arguments (given 1, expected 2)

The only exception is dynamic method definition: even if defined by passing a non-lambda proc, methods still have normal semantics of argument checking.

class C
  define_method(:e, &proc {})
end
C.new.e(1,2)       #=> ArgumentError
C.new.method(:e).to_proc.lambda?   #=> true

This exception ensures that methods never have unusual argument passing conventions, and makes it easy to have wrappers defining methods that behave as usual.

class C
  def self.def2(name, &body)
    define_method(name, &body)
  end

  def2(:f) {}
end
C.new.f(1,2)       #=> ArgumentError

Flash Messages in Rails

2020-02-25 00:35:08 +0000

What are flash messages?

A flash message is a way to communicate information with the users of your Rails application so they can know what happens as a result of their actions.

Example messages:

“Password changed correctly” (confirmation) “User not found” (error) You set these flash messages in your controllers, then you render them in your views. Your users can then act accordingly.

Let’s learn exactly how this works!

How to Use Flash Messages

You can work with these notification messages using the flash helper method.

It behaves a lot like a Ruby hash.

The flash object has methods like keys, any? or each & you can access a particular message with [].

What types of flash messages can you set?

By default you have:

  1. notice
  2. alert

Here’s an example of how to use it:

flash.alert = "User not found." 

Or if you prefer:

flash[:alert] = "User not found." 

(Only a style difference.)

You can use this code inside your controller actions, like index, create, new, etc.

Another way is this:

redirect_to :books_path, notice: "Book not found"

This allows you to redirect & create a flash message in one step.

Nice!

Alert vs Notice

As far as I understand it doesn’t really matter if you use alert or notice.

Use the one that feels more natural for your situation.

I like to think about alert as an error message & a notice as a confirmation message.

Separating them helps you style them differently.

For example:

You can show alerts in red & notices in green.

It’s also possible to create your own flash types by using the add_flash_types controller method.

Like this:

class ApplicationController
  add_flash_types :info, :error, :warning
end 

Rendering Flash Messages

Flash messages aren’t shown automatically.

You have to render them inside one of your views so users can see them.

Consider adding this to your application layout.

Here’s a code example:

<% flash.each do |type, msg| %>
  <div>
    <%= msg %>
  </div>
<% end %>

Put this wherever you want to show your notice, usually at the top of the page, below the menu bar.

Remember:

Once you render a message it’ll be removed from flash, so it won’t be shown again.

Styling Your Notices & Alert Messages

Flash messages don’t have any built-in design or style.

Solution?

If you’re using Bootstrap, you can use the “alert alert-info” CSS class to make flash messages look good.

Example:

<% flash.each do |type, msg| %>
  <div class="alert alert-info">
    <%= msg %>
  </div>
<% end %>

It looks like this:

If you’re NOT using Bootstrap, then you can write your own CSS to make it look however you want.

When Are Flash Messages Rendered?

Flash messages are only removed on your next controller action, after your display them.

Implications:

If you redirect_to, then render a flash message, that’s good If you redirect_to & DON’T render the message, the message will stick around, in the flash hash If you render on the same action that you’re setting the flash message, that flash message will be available, but NOT removed so it will stay around & potentially be shown twice So…

What if you want to set a flash message for the current action?

That’s where flash.now comes in!

Here’s an example:

def index
  @books = Book.all

  flash.now[:notice] = "We have exactly #{@books.size} books available."
end

This will render the index view.

The notice message will be shown & removed from flash so it won’t be shown twice.

In other words:

You only need to use flash.now if you’re going to render instead of redirecting.

Summary

You’ve learned about flash messages in Rails & how to use them correctly!

Btw, flash messages aren’t the same as validation errors. Validations are associated with the model object, and you access these validation messages with the errors method, like @user.errors.

Now it’s your turn to put this into practice by writing some code.

Thanks for reading!


Install Docker on Ubuntu 18.10

2020-02-19 00:22:50 +0000

useful image

let’s install Docker

Step 1: Update Local Database Update the local database with the command:

sudo apt-get update

Step 2: Download Dependencies You’ll need to run these commands to allow your operating system to access the Docker repositories over HTTPS.

In the terminal window, type:

tinix@yandex:/$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

To clarify, here’s a brief breakdown of each command:

  • apt-transport-https: Allows the package manager to transfer files and data over https
  • ca-certificates: Allows the system (and web browser) to check security certificates
  • curl: This is a tool for transferring data
  • software-properties-common: Adds scripts for managing software

Step 3: Add Docker’s GPG Key The GPG key is a security feature.

To ensure that the software you’re installing is authentic, enter:

tinix@yandex:/$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Add the repository

tinix@yandex:/$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Update again

tinix@yandex:/$ sudo apt-get update

install docker

 tinix@yandex:/$ sudo apt-get install docker-ce

start with the system

tinix@yandex:/$ sudo systemctl enable docker

add new user

for example check you user

tinix@yandex:/$ whoami
tinix
$ sudo usermod -aG docker tinix

leave session

tinix@yandex:/$ exit

start again with the new user and check

tinix@yandex:/$ docker run hello-world

that’s all folks..!!


Ruby vs Elixir , Rails vs Phoenix - part 2

2018-09-28 16:52:56 +0000

useful image

Dev Tools rake vs. mix In Ruby, there is rake, in Elixir there is mix.

Mix is a build tool that provides tasks for creating, compiling, and testing Elixir projects, managing its dependencies, and more.

Like Rails, Phoenix provides various mix commands to handle common tasks. Most of these commands should feel familiar:

mix phoenix.new my_app
mix phoenix.server
mix ecto.migrate
mix phoenix.gen.html User users email:string
mix test
MIX_ENV=test mix ecto.migrate
 

# irb vs. iex Ruby gives us the Interactive Ruby Shell (IRB or irb). IEx is Elixir’s Interactive Shell.

Run it within your Elixir project using the command: iex -S mix. The -S tells iex to execute the Mixfile (mix.exs), which handles configuring the project.

Unlike irb, you will have to hit Ctrl-C twice to exit, instead of Ctrl-D.

If you are like me and prefer to have a console session open while developing, usually with some state built up, then the recompile() helper will come in handy. Calling it eliminates having to start a new iex session (and lose all your state) when you’ve made changes to a file.

Another handy, time-saving tip:

Create a .iex.exs file in your project root to alias your project’s modules so you can call, Repo.all, instead of, MyApp.Repo.all.

The first time I fired up iex and wanted to grab the first User in the database, I got hit with:

(UndefinedFunctionError) function MyApp.User.first/0 is undefined or privateefinedFunctionError) function
 

Remember, Elixir is functional, so we can’t do things like User.first.

Here is the equivalent in Phoenix (technically Ecto, the database layer):

User |> Repo.all |> List.first
 

That is a lot of typing. Adding a couple convenience functions to my project’s Repo module allows me to call Repo.first User. That is better.

defmodule MyApp.Repo do
  use Ecto.Repo, otp_app: :elformo
  alias __MODULE__

  def first(query) do
    query |> Ecto.Query.first |> Repo.one
  end

  def last(query) do
    query |> Ecto.Query.last |> Repo.one
  end
end
 




subscribe via RSS