<commit_before># Metaprogramming

## How ruby works?



## Monkey patching 
* On matrix multiplection example

```
class Fixnum
  alias_method :plus, :+

  def self.adds
    @adds ||= 0
  end

  def self.adds=(arg)
    @adds = arg
  end

  define_method(:+) do |arg|
    self.class.adds = self.class.adds.send(:plus, 1)
    self.send(:plus,arg)
  end

end
```

## attr_whatever

```
```


## Send method

```
class People

  def initialize(name)  
  	@name = name
  end
  
  def wake_up
  	puts "#{@name} is waking up!"
  end
  
  def say_hello_to_mom
  	puts "#{@name} is saying hello to mom!"
  end
  
  def brush_teeth
  	puts "#{name} is brushing teeth!"
  end
  
  def take_coffee
  	puts "#{@name} is taking coffee!"
  end
  
  def go_out
  	puts "#{@name} is going out!"
  end
  
end

dima = People.new("Dima")

dima.wake_up
sleep 0.3

dima.say_hello_to_mom
sleep 0.3


dima.brush_teeth
sleep 0.3

dima.take_coffee
sleep 0.3


dima.go_out
sleep 0.3

```

```
%i(wake_up say_hello_to_mom brush_teeth take_coffee go_out).each do |action|
 dima.send(action)
 sleep 0.3
end
```

## Define methods

## Method_missing

```
class Object
  def not
    Not.new(self)
  end

  class Not
    def initialize(original)
      @original = original
    end

    def method_missing(sym, *args, &blk)
      @original.send(sym, *args, &blk)
    end
  end
end

class Person
  attr_reader :name
  
  def initialize(name)
    @name = name
  end
  
  def smith?
    @name == "Smith"
  end
end

guys = []
guys << Person.new("Smith")
guys << Person.new("New")
guys << Person.new("Trinity")
guys << Person.new("Morphius")

guys.each do |guy|
  if guy.smith?
  	puts "Kick #{guy.name} ass!"
  else
  	puts "Give #{guy.name} a candy!"
  end
end


```

## Evals


<commit_msg>working on notes for 3 lesson<commit_after># Metaprogramming

## Monkey patching 
* On matrix multiplection example

```
class Fixnum
  alias_method :plus, :+

  def self.adds
    @adds ||= 0
  end

  def self.adds=(arg)
    @adds = arg
  end

  define_method(:+) do |arg|
    self.class.adds = self.class.adds.send(:plus, 1)
    self.send(:plus,arg)
  end

end

## How ruby works?
```
ruby -e 'five = 1+4; puts five' --dump parsetree
ruby -e 'five = 1+4; puts five' --dump parsetree_with_comment
ruby -e 'five = 1+4; puts five' --dump insns
ruby -e 'five = 1+4; puts five' --dump yydebug
```
## Understanding self variable

The keyword self in Ruby gives you access to the current object – the object that is receiving the current message. To explain: a method call in Ruby is actually the sending of a message to a receiver. When you write obj.meth, you're sending the meth message to the object obj. obj will respond to meth if there is a method body defined for it. And inside that method body, self refers to obj. When I started with Ruby, I learned this pretty quickly, but it wasn't totally apparent when you might actually need to use self. I will outline the two most common use cases I've found for it.


## Ruby have ghosts
* http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html

```
Dog = Class.new
    
class Dog
    # some doggie behavior here
end

Dog.class
=> Class

dog = Dog.new

def dog.wark
 puts 'Wark'
end

snoopy = Dog.new

dog.wark
snoopy.wark

```


## Send method

```
class People

  def initialize(name)  
  	@name = name
  end
  
  def wake_up
  	puts "#{@name} is waking up!"
  end
  
  def say_hello_to_mom
  	puts "#{@name} is saying hello to mom!"
  end
  
  def brush_teeth
  	puts "#{name} is brushing teeth!"
  end
  
  def take_coffee
  	puts "#{@name} is taking coffee!"
  end
  
  def go_out
  	puts "#{@name} is going out!"
  end
  
end

dima = People.new("Dima")

dima.wake_up
sleep 0.3

dima.say_hello_to_mom
sleep 0.3


dima.brush_teeth
sleep 0.3

dima.take_coffee
sleep 0.3


dima.go_out
sleep 0.3

```

```
%i(wake_up say_hello_to_mom brush_teeth take_coffee go_out).each do |action|
 dima.send(action)
 sleep 0.3
end
```

## Define methods


## attr_whatever

```


```

## Method_missing

```
class Object
  def not
    Not.new(self)
  end

  class Not
    def initialize(original)
      @original = original
    end

    def method_missing(sym, *args, &blk)
      @original.send(sym, *args, &blk)
    end
  end
end

class Person
  attr_reader :name
  
  def initialize(name)
    @name = name
  end
  
  def smith?
    @name == "Smith"
  end
end

guys = []
guys << Person.new("Smith")
guys << Person.new("New")
guys << Person.new("Trinity")
guys << Person.new("Morphius")

guys.each do |guy|
  if guy.smith?
  	puts "Kick #{guy.name} ass!"
  else
  	puts "Give #{guy.name} a candy!"
  end
end


```

## Evals



{'fraction_non_alphanumeric': 0.11965442764578833, 'fraction_numerical': 0.009719222462203024, 'mean_word_length': 2.975107296137339, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4897183', 'n_tokens_mistral': 1882, 'n_tokens_neox': 1757, 'n_words': 542}