Hexa's Blog

Summary of block, process and lambda in Ruby

17/08/2015 cheatsheet

There are three ways to group trunk of code in Ruby which are block, process and lambda. Each of them behave differently from others. This post is all about the differences of them and its examples and use cases.

|-------------------------+--------------------+-------------+------------------------|
| Characteristics         | Process            | Block       | Lambda                 |
|-------------------------+--------------------+-------------+------------------------|
| Object                  | yes                | no          | yes                    |
|-------------------------+--------------------+-------------+------------------------|
| Number of arguments*    | many               | 1           | many                   |
|-------------------------+--------------------+-------------+------------------------|
| Checking number of args | no                 | identifying | yes                    |
|-------------------------+--------------------+-------------+------------------------|
| Return behavior         | affect outer scope | identifying | not affect outer scope |
|-------------------------+--------------------+-------------+------------------------|

Basic usage

 # block
 def test_function(&a)
   a.call
 end

 test_function {
   p "it's block"
 }
 # lambda
 lam = lambda{
   p "it's lambda"
 }
 lam.call #OR#
 test_function(lam)

 # Process
 pro = Proc.new {
   p "it's proc"
 }
 pro.call #OR#
 test_function(pro)

Object or not

  • Block is not an object, cannot execute directly, it need to be passed to a method
  • Proc and Lambda are objects, its instance can be execute directly

Number of block, proc and lambda passed in parameter field

  • Block: A method can use only one block which passed in the parameter fields. Well, obviously, block is a kind of anonymous function. If there are two passing in parameter field. How could interpreter understand when should it use this or that block. Meanwhile, a method can only use one block or anonymous function which is passed in parameter field.

  • Proc and Lambda: In fact, these two are identical and it’s object instances. On the other words, you are passing object in parameter field. Hence, pass them as many as you want.

Return behaviour

  • Block: return cannot be used within a block. Here is an article about block break and next behaviours
  • Lambda: return instruction within a block only suspend instruction execute within the block. It does not suspend outer method.
  • Process: return instruction also affect the outer scope. It suspends the outer method directly.

Checking number of arguments passing to block, process, lambda

|-------+-------+---------+--------|
|       | Block | Process | Lambda |
|-------+-------+---------+--------|
| check | no    | no      | yes    |
|-------+-------+---------+--------|

Reference

Generate entity relationship based on model, Ruby on rails

07/08/2015 Ruby on Rails 4

During this time, I am in an internship program. There is a big concern, I have to work with a very big project, and there is no documentation. The number of tables in project’s database is more than 20, still no documentation.

A big nightmare for an intern one. It’s important to make an entity relationship diagram, at least with a hope that I can get cope easily with the project.

Game on!, There is a gem named erd - url

Setup and Installation

  • Install graphviz (fedora)
sudo dnf install -y graphviz
  • Add gem erd to gem file
group :development do
  gem "rails-erd"
end
  • Install bundle
bundle install

Configuration

Configuration file will be loaded at ~/.erdconfig or ...project_rails/.erdconfig, file config in the root of project will take higher priority than in the home directory.

attributes:
  - content
  - foreign_key
  - inheritance
disconnected: true
filename: erd
filetype: pdf
indirect: true
inheritance: false
markup: true
notation: simple
orientation: horizontal
polymorphism: false
sort: true
warn: true
title: sample title
exclude: null
prepend_primary: false

Generating entity diagram file

Entity diagram will be generated in the root directory of project.

bundle exec erd

Highchart, forcing dual yAxis to have common zero

28/07/2015 etc

Highchart is a common javascript library which use to display graph with many beautiful features, however, there is a small need in use of highchart.js. It’s about having dual yAxis, and how to balance common zero between two yAxis.

There is no built-in feature that can help you deal with this solution but changing the min, max value via setExtremes() method.

I did write a small method which can help solve this problem, small but achievable. github

How to use

  1. Given that, on the html there is a div which is used for highcharts, this div is only for rendering graph for example $("#graph")
  2. After include the balancezero.js, you can test by running the command on the web console balanceZeroRoot(dom_element) or for example balanceZeroRoot($("#graph"))
  3. By default, there is exist behavior for show and hide plots, you need to modify those default behavior to work with balancezero.js. For each kind of graph, there is exist option name legendItemClick for example link
plotOptions: { // shared option on plottin the graph
  series: {
    borderColor: '#000000',
    pointStart: Date.parse(data.start_date),
    pointEnd: Date.parse(data.end_date),
    pointInterval: 24 * 3600 * 1000,
    groupPadding: 0, // group for each point on the x-axis
    shadow: false,
    animation: false,
    events: {
      legendItemClick: function(){
        if(this.visible == true){
          this.setVisible(false, false);
        }else {
          this.setVisible(true, false);
        }
        balanceZeroRoot(YOUR_GRAPH_DOM_ELEMENT);
        return false;
        }
    }
  }
}
  • In addition, there is also a need to load balanceZeroRoot() right after data loaded. There are many kind of graph, the code below is an example about chart type
chart: {
  events: {
    load: function (){
      balanceZeroRoot(YOUR_GRAPH_DOM_ELEMENT);
    }
  }
}

Note

  • The demand to have common zero for dual yAxis has been there for 2 years link , however there is no good solution which fit for me even the one from the admin of highcharts, the plugin does not work perfectly.

  • Highcharts’s admin response: link, jsfiddle link

Emacs, Ruby On Rails Configuration

16/05/2015 Ruby on Rails 4

Robe

1. Source: link 2. Features

  • Jump to read the documentation of methods
  • Complete the symbol at point, actually, it will show a list of available method for given character or class

3. Interactive Function

  • M-. to jump to the definition
  • M-, to jump back
  • C-c C-d to see the documentation
  • C-c C-k to refresh Rails environment
  • C-M-i to complete the symbol at point
  • ruby-load-file to update ruby file

Highlight Indentation

1. Source link 2. Feature

  • Color the method columns (scope)
  • User can differentiate current scope to upper and lower scope 3. Variables
(set-face-background 'highlight-indentation-face "#808080")
(set-face-background 'highlight-indentation-current-column-face "#e5e5e5")

4. Interactive Functions

  • highlight-indentation-current-column-mode: current column will be highlighted only or with particular colors.
  • highlight-indentation-mode: highlight all columns.

Ruby-Flymake

1. Source link 2. Feature

  • checking syntax

Reference List

  • Emacs configuration for rails,link

Conkeror, Deleting all history instantly

02/05/2015 Conkeror

There is a small function you have to write to delete your history instantly. source

function history_clear () {
    var history = Cc["@mozilla.org/browser/nav-history-service;1"]
        .getService(Ci.nsIBrowserHistory);
    history.removeAllPages();
}
interactive("history-clear",
    "Clear the history.",
    history_clear);

JavaScript learning

30/04/2015 cheatsheet

1. Function and Variable

a. Declare function

var function_name = function(){
//Do something here
}

b. Declare variable

var variable_name = 123;

c. Reuse method

var function_namedA = function(){
    this.age = 123;
    Console.log(this.age);
}
var Bob = {
    age = 12;
}
Bob.function_namedA();
//The age of Bob changed from 12 to 123

#2. Object a. Make an object

// type 1
var object_name = {
	variable_name1 = 123;
    variable_name2 = 123;
}
// type 2
object  = new Object();
object.variable_name1 = 123;

b. Make constructor of an object

function Person(job, age){
    this.job = job;
    this.age = age;
}

c. Use constructor of an object

var Bob = new Person('engineer', 23);

d. Use variables of an object

//type 1
var a = object[var_name]
//type 2
var a = object.var_name

e. Private and public variables and function

  • private variables are declared with the var keyword inside the object, and can only be accessed by private functions and privileged methods.
  • private functions are declared inline inside the object’s constructor (or alternatively may be defined via var functionName=function(){...}) and may only be called by privileged methods (including the object’s constructor).
  • privileged methods are declared with this.methodName=function(){...} and may invoked by code external to the object.
  • public properties are declared with this.variableName and may be read/written from outside the object.
  • public methods are defined by Classname.prototype.methodName = function(){...} and may be called from outside the object.
  • prototype properties are defined by Classname.prototype.propertyName = someValue
  • static properties are defined by Classname.propertyName = someValue
var Person = function(job, age){
    //job and age are public variables
    this.job = job;
    this.age = age;
	//sex is private variable
	var sex = 'male';
	//printJob() is a public function
    this.printJob(){
	    Console.log(this.job);
	}
	//sayHello() is private function
	var sayHello = function(){
	    Console.log('Hello');
	}
}
Person.variable = 123; //variable is pointing to object named Person
Person.prototype.variable = 345; //variable is pointing to the function of object named Person

#3. Inheritance a.Inheritance object

var a = {a: 1};
// a ---> Object.prototype ---> null

var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1 (inherited)

var c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null

var d = Object.create(null);
// d ---> null
console.log(d.hasOwnProperty);
// undefined, because d doesn't inherit from Object.prototype

#4. Notes

  • Keyword this, within a function, this refers to object which call the function.

Haivl mode for Conkeror

17/04/2015 Projects

This project is a project for hackday in Cogini company in 2014 1. Identify the page mode

define_keymaps_page_mode("haivl_mode",
       build_url_regexp($domain="haivainoi",
					    $allow_www = true,
					    $tlds = ["com", "tv"]),
       {normal: haivl_keymap},
       $display_name = "haivl");

2. Declare css selector, relative variables

var haivl = {};
haivl.selector = {};
haivl.selector.nav = ".top-menu.left>ul>li>a"
haivl.selector.seemore = ".button-readmore>a"
haivl.name = ["New", "Unread", "Vote","Video","Hot", "SeeMore"];

3. Declare function to make a click action to DOM node

haivl.doClick = function(I, index ){
  var document = I.buffer.document;
  var button_array = document.querySelectorAll(haivl.selector.nav);
  if(button_array[index] != null){
	dom_node_click(button_array[index]);
  }else {
 	I.minibuffer.message("Button: " + haivl.name[index] + " not found." + "length: "+ button_array.length);
  }
  I.minibuffer.message(I);
}
haivl.doClickSeeMore = function(I){
  var document = I.buffer.document;
  var button = document.querySelector(haivl.selector.seemore);

  if(button != null){
	dom_node_click(button);
  }else {
 	I.minibuffer.message("Button: " + haivl.name[5] + " not found.");
  }
}

4. Make those function become interactive

interactive("haivl-1","new feeds", function(I){
  haivl.doClick(I, 0);
});
interactive("haivl-2", "unread feeds",function(I){
  haivl.doClick(I,1);
});
interactive("haivl-3", "vote feeds", function(I){
  haivl.doClick(I,2);
});
interactive("haivl-4", "video feeds", function(I){
  haivl.doClick(I,3);
});
interactive("haivl-5", "hot feeds", function(I){
  haivl.doClick(I,4);
});
interactive("haivl-seemore", "see more feeds",function(I){
  haivl.doClickSeeMore(I);
})

5. Reference I must say thank to Tran Xuan Truong, Quan Bao Thien To. When I write this bunch of code I don’t know much about javascript. In addition, regarding Conkeror technical issues, I gained help from Tran Xuan Truong who is a master in Conkeror Web browser and he is one who has a big love in programming. Thank you, I will remember the hackday.

Right now, It’s April 14, 2015. I note this memory to remember a day of doing new things, learning new things and of course, because it’s a memorial hackday. Even though, currently, the haivl.com has been collapsed,but this project still work with haivainoi.com

Apache Web Server, Forbidden Error

17/04/2015 etc

Problem: Apache Web Server announces that Forbidden Error, given that developers configure Allow and Deny directory with no mistake Reason: A lack of Indexes for files in directory. Solution: Add option Indexes in directory tag <Directory>

Example: The following configuration causes forbidden error

<Directory "/home/pvt/apache2/htdocs">
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

The following configuration solve the problem

<Directory "/home/pvt/apache2/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

Bootstrap fonts working with rails 4, asset pipeline

09/04/2015 Ruby on Rails 4

Problems: Cannot load the fonts of bootstrap Reason: In Rails, all assets are loaded from host:port/assets not host:port/fonts Solution: Replace the source url in @font-face, from ../fonts/ to /assets

Original version:

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('../fonts/glyphicons-halflings-regular.eot');
  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}

Edited version:

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('/assets/glyphicons-halflings-regular.eot');
  src: url('/assets/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('/assets/glyphicons-halflings-regular.woff') format('woff'), url('/assets/glyphicons-halflings-regular.ttf') format('truetype'), url('/assets/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}

Music-api, a web-service to work with online music source

02/02/2015 Projects

Introduction

There is no need to descript more about the project, the main role of this project named music-api is to provide a web service for developers to exploit indirectly the song’s information coming from any online source such as ZingMp3, Nhaccuatui.

This project is an open source software, developers contribute and developer my project. This time, this is only two online source ZingMp3 and Nhaccuatui, however, the number source will be increased regarding developers’ demand.

The song information includes name, singers, lyrics, song's page and inparticular song's source for downloading.

Why does it work ?

Fundamentally, this service send a request to music oridinary servers, after receiving responses, it analyze the response (inspect elements selectively). After finished analysis, it send json object which inlcluding all song’s information. Currently, the web service is deployed at USA by heroku, Because of IP filter applying by VNG(ZingMp3), there are some songs which you cannot search. I have tested by using VPN locating in the USA, the result is limited.

Good news is that Nhaccuatui is very generous, they allow foreign IP to access all song, meanwhile, you can exploit from more songs.

How-to guide