Skip to content

Instantly share code, notes, and snippets.

@kenjiskywalker
Last active December 27, 2015 06:19
Show Gist options
  • Select an option

  • Save kenjiskywalker/7281133 to your computer and use it in GitHub Desktop.

Select an option

Save kenjiskywalker/7281133 to your computer and use it in GitHub Desktop.
メタプログラミングRubyとEloquent Ruby読んだ時のメモ
#!/usr/bin/env ruby
$foo = 10
class C
def method
puts "Method"
end
alias_method :new_method, :method
def new_method
method
puts "New Method"
end
alias $bar $foo
def new_global
puts $bar
end
end
C.new.method
# Method
C.new.new_method
# Method
# New Method
C.new.new_global
# 10
#!/usr/bin/env ruby
class MyClass
def hello
puts "Hello!"
end
alias_method :hello_with_log, :hello
def hello_with_log
puts "log start"
hello
puts "log end"
end
end
MyClass.new.hello
# Hello!
MyClass.new.hello_with_log
# log start
# Hello!
# log end
#!/usr/bin/env ruby
proc = Proc.new{|n|n + 1}
p proc.call(1)
# 2
puts "--- Proc.new ---"
proc = lambda{|n|n + 1}
p proc.call(1)
# 2
puts "--- lambda ---"
def yyield
if block_given?
yield
end
end
yyield{puts "hello"}
# hello
puts "--- 2 ---"
def pluse(a, b)
if block_given?
yield(a, b)
end
end
p pluse(100, 200){100 + 200}
# 300
puts "--- 3 ---"
def my_method(&the_proc)
the_proc
end
ppp = my_method{|name| "Hello, #{name}!"}
puts ppp.class
puts ppp.call("Hage")
tasu = my_method{|n, m| n + m}
p tasu.call(10,15)
# Proc
# Hello, Hage!
# 25
puts "--- 4 ---"
def math(a, b, c)
p block_given?
if block_given?
yield(a, c)
end
end
def teach_math(a, b, c, &operation)
puts "計算しよ"
if block_given?
puts math(a, b, c, &operation)
else
puts math(a, b, c)
end
end
teach_math(1, 2, 3){|n, m, o|n + m}
# 計算しよ
# true
# 4
#!/usr/bin/env ruby
class Blocks
attr_reader :name, :adana
def initialize(name, adana, &block)
@name = name
@adana = adana
@block = block
end
def name
"#{@name} #{@adana}"
end
def view
if @block
@view = @block.call
@block = nil
end
@view
end
end
b = Blocks.new('hage', 'hoge') do
10 * 10
end
p b.name
# "hage hoge"
p b.view
# 100
#!/usr/bin/env ruby
class MyClass
@@class_hensoo = "クラス変数"
@class_instance_hensoo = "クラスインスタンス変数"
def self.class_hensoo_view
@@class_hensoo
end
def self.class_instance_hensoo_view
@class_instance_hensoo
end
def instance_view
@instance_hensoo = "インスタンス変数"
end
end
puts MyClass.class_hensoo_view
# クラス変数
puts MyClass.class_instance_hensoo_view
# クラスインスタンス変数
puts MyClass.new.instance_view
# インスタンス変数
class Hasei < MyClass
def self.keisho_class_instance_hensoo_view
@class_instance_hensoo
end
def self.keisho_class_hensoo_view
@@class_hensoo
end
end
puts Hasei.class_hensoo_view
# クラス変数
puts Hasei.class_instance_hensoo_view
#
puts Hasei.new.instance_view
# インスタンス変数
puts "keisho_class_hensoo_view #{Hasei.keisho_class_hensoo_view}"
# keisho_class_hensoo_view クラス変数
puts "keisho_class_instance_hensoo_view #{Hasei.keisho_class_instance_hensoo_view}"
# keisho_class_instance_hensoo_view
# クラスインスタンス変数は継承先では利用できない
#!/usr/bin/env ruby
class Title
attr_reader :long_name, :short_name
def initialize(long_name, short_name)
@long_name = long_name
@short_name = short_name
end
end
class Author
attr_reader :first_name, :last_name
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
end
class BookLong
attr_reader :title, :author
def initialize(title, author)
@title = title
@author = author
end
def view
puts "#{@title.long_name} by #{@author.first_name} #{@author.last_name}"
end
end
class BookShort
attr_reader :title, :author
def initialize(title, author)
@title = title
@author = author
end
def view
puts "#{@title.short_name} by #{@author.last_name}"
end
end
title = Title.new('隣の客はよく柿食う客だ', '柿日記')
author = Author.new('山田', '太郎')
long = BookLong.new(title, author)
short = BookShort.new(title, author)
long.view
# 隣の客はよく柿食う客だ by 山田 太郎
short.view
# 柿日記 by 太郎
#!/usr/bin/env ruby
# irb> BasicObject.methods.grep(/instance_eval/)
# => [:instance_eval]
# irb> Object.methods.grep(/singleton_methods/)
# => [:singleton_methods]
class Foo
def initialize(&block)
@result = 0
begin
instance_eval(&block) ### ここで set とか add とかをブロックでメソッドに渡している
puts @result ### instance_eval の結果が @result に入っているので出力して確認
rescue => error
p error
end
end
def self.define(&block) ### defineはnew
Foo.new(&block)
end
def self.hage(&block)
Foo.new(&block)
end
def set(number)
@result = number
end
def add(number)
@result += number
end
def say(number)
@result = "say #{number}"
end
puts "singleton_methods : #{self.singleton_methods()}"
# singleton_methods : [:define, :hage]
end
Foo.new do
set 10
add 10
end
# 20
Foo.define do
set 10
add 10
end
# 20
Foo.hage do
set 10
add 10
end
# 20
Foo.define do
say "hage"
end
# say hage
# --- error ---
# Foo.define do
# mage 10
# end
# <NoMethodError: undefined method `mage' for #<Foo:0x007faaea0a7bb0 @result=0>>
#!/usr/bin/env ruby
plus = "1 + 1"
p eval(plus)
# 2
#!/usr/bin/env ruby
require 'pp'
def kaiwa(x = "me", y = "me")
"#{x} and #{y}"
end
puts kaiwa()
# me and me
puts kaiwa("I")
# I and me
puts kaiwa(nil, nil)
# and
puts kaiwa("I", "you")
# I and you
def matomeru(*args)
args.map{|arg|arg}
end
p matomeru('abc','123','xyz')
# ["abc", "123", "xyz"]
#!/usr/bin/env ruby
class Hoge
attr_accessor :name_hash
def add_name(names_hash)
@name = names_hash
end
def show_name
puts @name
end
end
h = Hoge.new
h.add_name( :name => 'yamada', :size => 12)
h.show_name
# {:name=>"yamada", :size=>12}
#!/usr/bin/env ruby
require 'pp'
movie = { title: '2001', genre: 'sci fi', rating: 10 }
movie.each do |entry|
pp entry
end
# [:title, "2001"]
# [:genre, "sci fi"]
# [:rating, 10]
movie.each do |name,value|
puts "#{name} => #{value} "
end
# title => 2001
# genre => sci fi
# rating => 10
#!/usr/bin/env ruby
parson = {}
parson[:name] = 'yamada'
parson[:adana] = 'taro'
puts "name is #{parson[:name]}, adana is #{parson[:adana]}"
# name is yamada, adana is taro
#!/usr/bin/env ruby
class Parent
def self.inherited(child) #inherited 継承された時のhook
puts "#{child} has inherited #{self}"
end
end
class Child < Parent
end
# Child has inherited Parent
#!/usr/bin/env ruby
require 'pp'
words = %w{ Hello Hi Hage }
pp words.map { |word| word.size }
# [5, 2, 4]
#!/usr/bin/env ruby
module M
def hoge_method
puts "hoge"
end
end
class C
include M
end
class D < C
end
D.new.hoge_method
class Hage
p self.ancestors()
# [Hage, Object, Kernel, BasicObject]
p self.superclass()
# Object
p self.class()
# Class
p self.methods()
# [:allocate, :new, :superclass, :freeze, :===, :==, :<=>, :<, :<=, :>, :>=, :to_s, :inspect, :included_modules, :include?, :name, :ancestors, :instance_methods, :public_instance_methods, :protected_instance_methods, :private_instance_methods, :constants, :const_get, :const_set, :const_defined?, :const_missing, :class_variables, :remove_class_variable, :class_variable_get, :class_variable_set, :class_variable_defined?, :public_constant, :private_constant, :module_exec, :class_exec, :module_eval, :class_eval, :method_defined?, :public_method_defined?, :private_method_defined?, :protected_method_defined?, :public_class_method, :private_class_method, :autoload, :autoload?, :instance_method, :public_instance_method, :nil?, :=~, :!~, :eql?, :hash, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
@hoge = 1
p self.instance_variables()
# [:@hoge]
end
#!/usr/bin/env ruby
class Foo
def initialize(name)
@method = name
end
def method_missing(method)
if method.to_s =~ /one|two/
@method.send("method_#{method}")
end
end
# method_#{name} があるかないかのチェック
def respond_to?(method)
# @method.respond_to?("method_#{method}")
@method.respond_to?("method_#{method}") || super
# super は見つからなければ
# irb> Object.methods.grep(/respond_to/)
# => [:respond_to?]
# Objectの respond_to? を呼ぶ
end
end
class Bar
def method_one
"one"
end
def method_two
"two"
end
end
foo = Foo.new(Bar.new)
p foo.one
# "one"
p foo.two
# "two"
p foo.three
# nil
p foo.respond_to?("one")
# true
p foo.respond_to?("two")
# true
p foo.respond_to?("three")
# false
#!/usr/bin/env ruby
class A
private
def hoge
puts "hello!"
end
end
# A.new.hoge
# error
class B < A
def hoge
super
end
end
B.new.hoge
# hello!
class Moji
def initialize(moji)
@moji = moji
end
def moji_count(moji)
return @moji.size
end
def moji_print
puts moji_count(@moji)
end
private :moji_count
end
moji = Moji.new('aaa')
moji.moji_print
# 3
#!/usr/bin/env ruby
class C
def def
puts "no tokui"
end
end
C.new.def
# "no tokui"
# ------------------------
c = C.new
def c.tokui1
puts "tokui 1"
end
c.tokui1
# tokui 1
# ------------------------
class << c
def tokui2
puts "tokui 2"
end
end
c.tokui2
# tokui 2
# ------------------------
class C
def self.tokui3
puts "tokui 3"
end
end
C.tokui3
# tokui 3
# ------------------------
C.singleton_class.send(:define_method, :tokui4) {puts "tokui 4"}
C.tokui4
# tokui 4
# ------------------------
C.new.def
# no tokui
#!/usr/bin/env ruby
class Foo; end
foo = Foo.new
# Object にメソッドはやす
def foo.bar
puts "bar~~~"
end
foo.bar
object = "foo"
class << object
def tokui
"tokui dayo"
end
end
p object.tokui
#!/usr/bin/env ruby
def yield_test
yield
end
yield_test{puts "test"}
# "test"
def yield_test2
yield "yield test"
end
yield_test2{|hoge| puts hoge}
# "yield test"
def yield_test3
yield "hoge"
end
yield_test3{|x| puts x}
# "hoge"
def yield_test4
yield 5,10
end
yield_test4{|x, y| puts x * y }
# 50
def yyy
yield("Hello!") if block_given?
end
# Hello Hello!
yyy{|hello| puts "Hello #{hello}"}
12.times do |x|
puts "#{x}"
end
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
# 11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment