じゃあ、いつRails始めるの?... 今でしょ!

[Ruby] : じゃあ、いつRails始めるの?… 今でしょ!

Index

  1. はじめに
  2. RailsのInstall
  3. Railsの基礎
  4. Rubyの基礎文法

はじめに

Ruby on Rails入門 (全46回) - プログラミングならドットインストール はてなブックマーク - Ruby on Rails入門 (全46回) - プログラミングならドットインストール
PythonistaからRubyistへの鞍替えを試みている@yutakikucです。DotInstall等を通してRuby on Railsの基礎を学び中なので学習した内容をまとめていきます。Yahoo!勤務時代はWebFWを自作していた経験もありFWについてはある程度知識を持っている僕から見てもRailsはとても便利ものだということが直ぐに分かりますが、色々と自動的にやり過ぎてくれて理解が難しくもあったりします。このエントリー内容は超初歩的なものになるので、これから勉強したいという人向けに記述します。この記事の基礎となっているのはdotainstallです。dotainstallのlessonは全部で46回ありますが、#4,#5,#09〜#036を見ると良いと思います。

RailsのInstall

環境

RailsをInstallする環境はCentOS6.3です。

$ cat /etc/redhat-release 
CentOS release 6.3 (Final)
RailsInstallに必要なPackageInstall

RailsのInstallに必要なPackageを先にInstallしておきます。以下のPackageが無いとRailsのInstall時にErrorが大量に出力される可能性があります。

$ sudo yum install gcc zlib zlib-devel yaml openssl openssl-devel curl curl-devel sqlite sqlite-devel readline readline-devel mysql mysql-devel -y
NodeのInstall

後々に必要になるServerSideのJavascriptの実行環境としてNodeをInstallしておきます。yumからinstall出来なかったのでSourceを直接DownloadしてCompileします。※注意:rails newでプロジェクトを作成した後にGemfileを修正してtherubyracerをinstallすればNodeは必要無くなります。

$ wget -N http://nodejs.org/dist/node-latest.tar.gz
$ tar xzf node-latest.tar.gz
$ cd node-v0.10.5
$ ./configure
$ make && sudo make install
RubyのInstall

Ruby 2.0.0-p0 リリース はてなブックマーク - Ruby 2.0.0-p0 リリース
最新のRuby versionは2.0.0です。これをダウンロードしてinstallします。ruby -vとgem -vでinstallを確認します。

$ wget "ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p0.tar.gz"
$ tar xzf ruby-2.0.0-p0.tar.gz
$ ./configure
$ make && sudo make install
$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
$ gem -v
2.0.0
RailsのInstall

gemでinstallするだけです。gemでのLibraryInstall先は標準の場合/usr/local/lib/ruby/gems/になるので覚えておくと良いと思います。

$ sudo gem install rails
$ rails -v
Rails 3.2.13
Railsの新しいProject作成とWebrickの起動

Railsの新しいProjectを作成し、Railsに同包されているWebrickを起動します。起動後にRailsProjectが動作することを確認します。これで一旦RailsInstallの説明は完了です。

$ rails new sample
  create  
  create  README.rdoc
  create  Rakefile
  create  config.ru
  create  .gitignore
  create  Gemfile
  create  app
  create  app/assets/images/rails.png
.......
  run  bundle install
.......
Your bundle is complete!

$ cd sample
$ rails s
=> Booting WEBrick
=> Rails 3.2.13 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2013-05-03 01:38:57] INFO  WEBrick 1.3.1
[2013-05-03 01:38:57] INFO  ruby 2.0.0 (2013-02-24) [x86_64-linux]
[2013-05-03 01:38:57] INFO  WEBrick::HTTPServer#start: pid=3729 port=3000

$ w3m "http://localhost:3000"
  • Browse the documentation

  □ Rails Guides
  □ Rails API
  □ Ruby core
  □ Ruby standard library

Welcome aboard

You’re riding Ruby on Rails!

Railsの基礎

RailsMVCのFWです。

Rails Command

rails newで新しいプロジェクトを作成します。ここではプロジェクト名をsampleとします。--skip-bundleというオプションを付けることで既にinstallされているgemを新たに追加せずにプロジェクトを作成することができます。※注意:RailsのdefaultでのDBはsqlite3なので、mysqlにしたい場合は-dオプションを付ける必要があります。

$ rails new sample
$ rails new sample -d mysql

rails generateでModel/Controllerを作成します。generateはgと省略することができます。ここでは名簿管理をするModelを作成します。Listという名前のmodelで名前と年齢を管理します。name:string age:integerはデータ型の定義です。

$ rails g model List name:string age:integer
  invoke  active_record
  create    db/migrate/20130503163317_create_lists.rb
  create    app/models/list.rb
  invoke    test_unit
  create      test/unit/list_test.rb
  create      test/fixtures/lists.yml

Controllerの生成もModelと同じようにgenerate出来ます。命名規則ですがControllerは複数形、Modelは単数形にします。ControllerのgenerateでViewも作成されます。

$ rails g controller Lists
  create  app/controllers/list_controller.rb
  invoke  erb
  create    app/views/list
  invoke  test_unit
  create    test/controllers/list_controller_test.rb
  invoke  helper
  create    app/helpers/list_helper.rb
  invoke    test_unit
  create      test/helpers/list_helper_test.rb
  invoke  assets
  invoke    coffee
  create      app/assets/javascripts/list.js.coffee
  invoke    scss
  create      app/assets/stylesheets/list.css.scss

generateで作成されたModelをmigrationします。DBへの反映はrakeコマンドを使います。

$ rake db:migrate
==  CreateLists: migrating ====================================================
-- create_table(:lists)
   -> 0.0045s
==  CreateLists: migrated (0.0046s) ===========================================

URLのroutingを設定するにはconfig/routes.rbファイルを修正し、rakeコマンドで反映します。まずはroutes.rbにを以下のようにresources :listsを追加してrake routesコマンドで反映します。rake routesコマンドで生成された内容を見ても分かるようにURLのFormatとHTTPMethodで呼び出したい処理の切り替えができるようになっていて、綺麗な形式になっています。

Sample::Application.routes.draw do

  resources :lists
$ rake routes
lists GET    /lists(.:format)          lists#index
      POST   /lists(.:format)          lists#create
 new_list GET    /lists/new(.:format)      lists#new
edit_list GET    /lists/:id/edit(.:format) lists#edit
 list GET    /lists/:id(.:format)      lists#show
      PUT    /lists/:id(.:format)      lists#update
      DELETE /lists/:id(.:format)      lists#destroy

rails consoleでrailsのdebugを行います。下ではListに対してnameとageのデータを格納するための処理をdebugしています。処理を行ったsqlも表示されています。

$ rails console
irb(main):002:0> l = List.new(:name => 'Kikuchi', :age => 30 )
=> #
irb(main):003:0> l.save
   (0.7ms)  begin transaction
  SQL (68.3ms)  INSERT INTO "lists" ("age", "created_at", "name", "updated_at") VALUES (?, ?, ?, ?)  [["age", 30], ["created_at", Fri, 03 May 2013 18:00:33 UTC +00:00], ["name", "Kikuchi"], ["updated_at", Fri, 03 May 2013 18:00:33 UTC +00:00]]
   (59.5ms)  commit transaction
=> true

rails dbconsole(rails db)でdbへの格納が正常に行われているかどうかを確認します。

$ rails db
sqlite> .tables
lists              schema_migrations
sqlite> select * from lists;
1|Kikuchi|30|2013-05-03 18:00:33.753423|2013-05-03 18:00:33.753423
sqlite> .exit

rails destroyで作成したファイルを削除することが出来ます。destroyはdと省略することができます。

$ rails d model List
$ rails d controller Lists
$ rails d migration lists 

rails serverで作成したプロジェクトをWebRickで確認できるようにします。serverはsと省略することができます。※rails sは作成したプロジェクトの直下で実行する必要あります。

$ rails s
Railsの日本語化と文字コードの設定

まずはbundle listでi18nが入っていることを確認します。入っていればconfig/localesディレクトリに移動して、rails-i18n/rails/locale/ja.yml at master · svenfuchs/rails-i18n · GitHub はてなブックマーク - rails-i18n/rails/locale/ja.yml at master · svenfuchs/rails-i18n · GitHubのja.ymlファイルをdownloadします。

$ bundle list | grep i18n
  * i18n (0.6.4)
$ cd config/locales
$ wget "https://raw.github.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml"
$ head ja.yml
ja:
  date:
abbr_day_names:
- 日
- 月
- 火
- 水
- 木
- 金
- 土

downloadしたymlファイルを有効化するためにconfig/application.rbを修正します。日本語化を行うためにconfig.i18n.default_locale = :jaに設定します。また文字コードutf-8にしたいのでconfig.encoding = 'utf-8'を追記します。

require File.expand_path('../boot', __FILE__)

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env)

module Sample
  class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.

# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'

# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.encoding = 'utf-8'
config.i18n.default_locale = :ja 
  end 
end
RailsのDirectory構成

bundle installしたDirectoryの中身は以下のようになります。
GemfileがProject全体のLibraryの管理などをするファイルです。ここを更新して必要なLibraryをinstallすることができます。
app/models,views,controllersにmvcファイルをそれぞれ設置します。app/assetsにimg,css,javascriptを設置します。
config/application.rbにapplication全体の設定、config/database.ymlにdbの設定、urlの設定はroutes.rbに記述します。
accesslogはlog/development.logに記録されます。

$ tree
.
├── Gemfile
├── Gemfile.lock
├── README.rdoc
├── Rakefile
├── app
│   ├── assets
│   │   ├── images
│   │   │   └── rails.png
│   │   ├── javascripts
│   │   │   └── application.js
│   │   └── stylesheets
│   │       └── application.css
│   ├── controllers
│   │   └── application_controller.rb
│   ├── helpers
│   │   └── application_helper.rb
│   ├── mailers
│   ├── models
│   └── views
│       └── layouts
│           └── application.html.erb
├── config
│   ├── application.rb
│   ├── boot.rb
│   ├── database.yml
│   ├── environment.rb
│   ├── environments
│   │   ├── development.rb
│   │   ├── production.rb
│   │   └── test.rb
│   ├── initializers
│   │   ├── backtrace_silencers.rb
│   │   ├── inflections.rb
│   │   ├── mime_types.rb
│   │   ├── secret_token.rb
│   │   ├── session_store.rb
│   │   └── wrap_parameters.rb
│   ├── locales
│   │   └── en.yml
│   └── routes.rb
├── config.ru
├── db
│   ├── development.sqlite3
│   └── seeds.rb
├── doc
│   └── README_FOR_APP
├── lib
│   ├── assets
│   └── tasks
├── log
│   └── development.log
├── public
│   ├── 404.html
│   ├── 422.html
│   ├── 500.html
│   ├── favicon.ico
│   ├── index.html
│   └── robots.txt
├── script
│   └── rails
├── test
│   ├── fixtures
│   ├── functional
│   ├── integration
│   ├── performance
│   │   └── browsing_test.rb
│   ├── test_helper.rb
│   └── unit
├── tmp
│   ├── cache
│   │   └── assets
│   ├── pids
│   │   └── server.pid
│   ├── sessions
│   └── sockets
└── vendor
├── assets
│   ├── javascripts
│   └── stylesheets
└── plugins

40 directories, 40 files
Contollerの作成

rake routesで表示されたメソッドをapp/controllers/lists_controller.rbに定義します。定義するメソッドはindex/create/new/edit/show/update/destroyですが、ここでは簡単な説明のため一覧表示のindexだけを説明します。newとcreateが少し定義がややこしいんですが、newは新規登録画面を呼び出し、createはnewからデータを受け取ってDBに格納する感じだそうです。rubyメソッド定義はdef〜endでできるので、def indexを作成します。@listsのようにインスタンス変数に格納したデータはview側で参照が出来ます。データをViewで呼び出すようにapp/views/lists/index.html.erbを定義します。定義したviewを閲覧するためにw3mコマンドでhttp://localhost:3000/listsにアクセスすると想定していたデータが取得出来ました。またlogs/development.logにaccesserrorのlogが記録されます。

class ListsController < ApplicationController

   def index
  #modelは単数形なのでList それを全て取得する
  @lists = List.all
   end

end
<% @lists.each do |list| %>
  • Name : <%= list.name %> Age : <%= list.age %>
  • <% end %>
    $ w3m "http://localhost:3000/lists"
    Name : Kikuchi Age : 30
    
    $ tail logs/development.log
    Started GET "/lists" for 127.0.0.1 at 2013-05-04 03:28:45 +0900
    Processing by ListsController#index as HTML
      ^[[1m^[[35mList Load (0.2ms)^[[0m  SELECT "lists".* FROM "lists"
      Rendered lists/index.html.erb within layouts/application (5.3ms)
    Completed 200 OK in 16ms (Views: 14.1ms | ActiveRecord: 0.2ms)

    Viewの中では<% %>、<%= %>などのrubyを埋め込むためのERB記号やhelperとしての便利メソッドが用意されています。標準でのhelperはgemでactionpackというLibraryをinstallした時点で/usr/local/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0.rc1/lib/action_view/helpers/に様々なhelperが追加されます。link_toというメソッドはurl_helper.rbというファイルに定義されています。また自分でhelperを追加したい場合はapp/helpers/application_helper.rb にdef〜endで定義します。
    list_pathというようなものはhelperは自動的に定義されるようです。_pathとすることでactionに関するURLを生成してくれます。更に__pathなどのControllerで定義したメソッドのURLも呼び出す事ができます。その他のViewに関する使い方は以下のページが参考になると思います。ビュー(view) - Railsドキュメント はてなブックマーク - ビュー(view) - Railsドキュメント

    <% %>    #rubyの命令が使える。
    <%= 文字列 %>  #実体参照系でescapeを行った上で表示する。
    <%= 文字列.html_safe %>  #escapeせずに出力する場合
    <%== 文字列 %>  #escapeせずに出力する場合
    <%= link_to 'home', '/' %>  #linkを生成
    <%= link_to 'list', list_path(list) %>   #listへのリンクを生成
    <%= link_to 'new', new_list_path() %> #newへのリンクを生成
    <%= image_tag("image.png",:size=>"50x50",:alt=>"画像") %> #画像を埋め込み 引数でsizeとaltを指定できる。
    
          def link_to(name = nil, options = nil, html_options = nil, &block)
        html_options, options = options, name if block_given?
        options ||= {}
    
        html_options = convert_options_to_data_attributes(options, html_options)
    
        url = url_for(options)
        html_options['href'] ||= url 
    
        content_tag(:a, name || url, html_options, &block)
      end 
    
    ModelにValidationを設定

    値のCheckを行いたい場合はValidatesを使うことができます。ValidatesはModelに仕込みます。Validatesに関しては以下のページに詳しく説明が載っています。Ruby on Rails Guides: Active Record Validations and Callbacks はてなブックマーク - Ruby on Rails Guides: Active Record Validations and Callbacks

    class List < ActiveRecord::Base
       
       validates :name, :presence => true   #nameは必須とする
       validates :age,  :presence => true, :length => {:maxinum => 3 }  #ageは必須で、最大の長さは3とする
    
    end
    
    sqlite3からMysqlへのmigration

    RailsのDefaultDBはsqlite3です。rails newの説明でも書きましたがMysqlを使用したい場合はオプションでdatabaseをMysqlに変更する必要があります。もし途中からMysqlに変更したくなった場合の方法をここでは記載します。まずはsqlite3のdataをymlファイルとしてdumpします。そのためにはGemfileにgem 'yaml_db'を追記してbundle installします。dumpする実行コマンドはrake db:dumpです。次にconfig/database.ymlをsqlite3からmysql2に変更します。最後にdumpしたファイルをrake db:loadしてデータのmigraionは完了になります。

    $ vi Gemfile # gem 'yaml_db',  gem 'mysql2'を追記
    $ rake db:dump
    $ vi config/database.yml  #sqlite3→mysql2に変更
    development:
      adapter: mysql2
      pool: 5
      timeout: 5000
      username: "root"
      password: ""
      database: "lists"
      socket: /var/lib/mysql/mysql.sock 
    $ rake db:load
    -- create_table("lists", {:force=>true})
       -> 0.1321s
    -- initialize_schema_migrations_table()
       -> 0.0572s
    -- assume_migrated_upto_version(20130504004202, ["/home/yuta/work/rails/sample/db/migrate"])
       -> 0.0283s

    Rubyの基礎文法

    Rubyの基礎文法についてもまとめを書いておきます。文法が少しPythonに似ているところもあってPythonistaとしてはRubyはとても学習しやすい言語だと感じました。

    CommentOut

    単数行は#、複数行は=begin,=endで囲みます。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    =begin
    print "Hello World!" #改行無しで出力
    =end
    
    オブジェクト指向

    rubyでは全てをオブジェクトで扱うと考えます。オブジェクトとはデータとメソッドを持つ型です。メソッドはデータ.メソッド()のように記述します。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    puts  "Hello World!".length()  # Hello World!という文字列オブジェクトに対してlengthメソッドがある。出力は12
    puts  length( "Hello World!" ) # error
    
    出力の違い

    以下ではprint,puts,pの違いを書きます。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    print "Hello World!" #改行無しで出力
    puts "Hello World!"  #改行ありで出力
    p "Hello World!"       #データの型を明示して出力
    
    破壊的メソッド

    破壊的メソッドは変数を上書きしてしまう仕組みです。以下の例を見たほうが分かりやすいと思います。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    #破壊的メソッド
    s = "Hello World!"
    puts s.chop      #sは上書きされず、Hello Worldが出力される。
    puts s               #sは上書きされていないので、Hello World!が出力される。
    puts s.chop!     #sは上書きされていて、Hello Worldが出力される。
    puts s               #sは上書きされていて、Hello Worldが出力される。
    
    文字列追記

    書き方が幾つかあります。少し調べてみたところ+=は処理コストが大きいようなので、それ以外を選択するのが良いと思います。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    #文字列の追記
    s = "Hello World!"
    s << " New World!"          # << による追記
    s += " Next World!"         # += による追記
    s.concat( " Last World!" )  # concat による追記
    puts s
    
    文字列検索

    index,includeメソッドで文字列に特定の文字が含まれるか検索できます。indexは検索文字の位置を特定、includeはtrue/falseを取得出来ます。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    #文字列の検索
    s = "Hello World!"
    puts s.index( "llo" )      #文字列が現れる位置を出力 結果は2
    puts s.include?( "foo" ) #文字列が含まれるかどうかをtrue/falseで返す。結果はfalse
    
    文字列の置換

    最初の文字列だけを置換する場合はsub、文字列全てを置換する場合はgsubを利用します。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    #文字列の置換
    s = "foo foo bar"
    puts s.sub( "foo", "bar" )    #最初の文字列を置換
    puts s.gsub( "foo", "bar" )  #文字列全てを置換
    
    配列

    配列の定義は[]の中にカンマで区切ります。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    #配列の定義
    values = [1,2,3,4,5]
    puts values        #配列の中身全てを出力
    puts values[2..3]  #配列の添字が2〜3を出力
    puts values[2...3] #配列の添字が2〜3で、最後の中身を含めずに出力
    puts values[0]     #最初の要素を出力
    puts values[-1]    #最後の要素を出力
    
    配列操作

    配列の要素を操作するunshift/push/shift/pop/uniq/sort/joinを説明します。unshiftで先頭に要素を追加、pushで末尾に要素を追加、shiftで先頭から要素を取り出す、popで末尾から要素を取り出す、uniqで重複削除、sortで昇順にsort.reverseで降順に並び替え、joinで要素を結合する事ができます。またinclude?で要素が含まれるかをtrue/falseで確認することができます。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    #配列の操作
    values = [1,2,3,4,5]
    puts values.shift     #先頭から要素を取り出す
    puts values.pop       #末尾から要素を取り出す
    values.unshift(0)     #先頭に要素を追加する
    values.push(6)        #末尾に要素を追加する
    values.push(0)
    puts values.uniq      #配列の要素をuniq
    puts values.push(1).sort #配列の要素をsort 
    puts values.sort.reverse #配列の要素を降順にsort
    
    #配列の要素をチェック
    if values.include?(6)
       puts "6 is exist"
    end
    
    #配列の要素を結合
    puts values.join( " and " )
    
    連想配列の定義

    連想配列の定義は{}とkey/value間は=>で定義します。each文で定義したkey/valueを抽出でき、has_key,has_valueでkey/valueの存在を確認する事ができます。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    # 連想配列
    scores = { "KIKUCHI"=>100, "TANAKA"=>70, "KATO"=>30 }
    scores.each do |key,value|
       puts "#{key}'s score is #{value}"
    end
    
    key = "KIKUCHI"
    if scores.has_key?(key)
       puts "#{key}' key is exist"
    else
       puts "#{key}' key is not exist"
    end
    
    value = 50
    if scores.has_value?(50)
       puts "#{value} is exist"
    else
       puts "#{value} is not exist"
    end
    
    制御文法

    ここではif/for/while/times/eachについて書きます。制御文はif/for/while〜endで定義します。繰り返しの方法にはその他timesやeachがあり、eachは連想配列のkey/valueを参照するときに使えると思います。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    # 制御文法
    ## 制御文法はif/for/while等〜endとして定義する
    str = "Hello World!"
    # if
    if str.include?("!")
       puts "str includes !"
    end
    
    ## 以下全部10回繰り返す
    # for
    for i in 1..10 do
      puts "Hello World! #{i}" 
    end
    
    # each
    data = 1..10
    data.each do |i|
      puts "Hello World! #{i}" 
    end
    
    # while
    i = 1
    while i <= 10 do
      puts "Hello World! #{i}"
      i+=1 
    end
    
    # times
    10.times do |i|
      puts "Hello World! #{i+1}"
    end 
    
    ## 連想配列の繰り返し
    scores = { "KIKUCHI" => 100, "TANAKA" => 70, "KATO" => 30  }
    scores.each do |key,value|
       puts "#{key}'s score is #{value}"
    end
    
    メソッドの定義

    新たにメソッドを追加したい場合はdef〜endで定義します。当然returnで値を返すこともできます。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    #出力メソッドを新たに定義
    def echo( word = "foo" )
       puts word,word
    end
    
    #10で割り切れるかを確認するメソッド
    def div10( value )
      if value % 10 == 0
    return true
      else
    return false  
      end
    end
    
    echo( "Hello World!" )
    puts div10( 3 )
    puts div10( 10 )
    
    Classの定義

    Classの定義はClass〜endで行います。また継承も使うことができて 継承したいClass < 継承元Classのように行います。

    #!/usr/bin/env ruby
    # -*- encoding: utf-8 -*-
    
    # AnimalClassを定義
    class Animal
       def initialize(name)
      @name = name
       end 
       def echo(word)
      puts word
       end 
    end
    
    # AnimalClassを継承するDogClassを定義
    class Dog < Animal
       def run 
      puts @name + " is running!"
       end 
    end
    
    pochi = Dog.new( "pochi" )
    pochi.run
    pochi.echo("wanwan")