rake db:migrate
rake db:test:prepare
rake db:fixtures:load
rake spec:db:fixtures:load
Whenever you start a process to handle requests with Rails (such as a Webrick server), one of the first things that happens is that config/environment.rb is loaded. For instance, take a look at the top of public/dispatch.rb:
require File.dirname(__FILE__) + “/../config/environment”
A word of caution: If you were to set the RAILS_ENV environment variable to production here, or the constant variable RAILS_ENV for that matter, it would cause everything you did in Rails to run in production mode. For instance, your test suite would not work correctly, since test_helper.rb sets RAILS_ENV to test right before loading the environment.
ENV["RAILS_ENV"] = "test"再是:
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")而在加载environment.rb时,又将RAILS_ENV覆写为prodoction。
# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '2.0.1' unless defined? RAILS_GEM_VERSION
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
RAILS_ROOT is used all over the place in the Rails codebase for finding files
read the config/environment.rb file as text (minus the commented lines) and parse out the RAILS_GEM_VERSION setting with a regexp.
parse_gem_version(read_environment_rb)
def parse_gem_version(text)
$1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*'([!~<>=]*\s*[\d.]+)'/
end
def read_environment_rb
File.read("#{RAILS_ROOT}/config/environment.rb")
end
def default_frameworks
[ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ]
end
def default_load_paths
paths = ["#{root_path}/test/mocks/#{environment}"]
# Add the app's controller directory
paths.concat(Dir["#{root_path}/app/controllers/"])
# Then components subdirectories.
paths.concat(Dir["#{root_path}/components/[_a-z]*"])
# Followed by the standard includes.
paths.concat %w(
app
app/models
app/controllers
app/helpers
app/services
components
config
lib
vendor
).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
paths.concat builtin_directories
end
def builtin_directories
# Include builtins only in the development environment.
(environment == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
end
def default_plugin_paths
["#{root_path}/vendor/plugins"]
end
It is the place for Rails to include application behavior (meaning models, helpers, and controllers). You can think about it as kind of like a framework-provided plugin mechanism.
you should rarely need to explicitly load Ruby code in your Rails applications (using require) if you follow the naming conventions.
Rails::Initializer.run do |config|里面的代码是关于Configuration的
...
end
# Settings in config/environments/* take precedence over those specified here.
The comment reminds you that the settings in the mode-specific environment files will take precedence over settings in environment.rb, which is essentially because they are loaded afterward and will overwrite your settings.
# Skip frameworks you're not going to use (only works if using vendor/rails).如果项目中不用数据库,就去掉Active Record,如果不用Web service或Email,也去掉相应的模块
# To use Rails without a database, you must remove the Active Record framework
# config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
Ruby is, of course, interpreted, and if you can get away with a smallersized codebase for the interpreter to parse, you should do so, simply for performance reasons.
# Only load the plugins named here, in the order given. By default, all pluginsplugins默认是按照字母顺序load的,也可以指定先load哪些plugin,再load剩下的(:all)
# in vendor/plugins are loaded in alphabetical order.
# :all can be used as a placeholder for all plugins not explicitly named
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
Rails takes advantage of the fact that Ruby provides a callback mechanism for missing constants. When Rails encounters an undefined constant in the code, it uses a classloader routine based on file-naming conventions to find and require the needed Ruby script.
Want to see the contents of your project’s load path? Just fire up the console and type $:
Use the normal environment settings for development mode, but point its database connection to a production database server. It’s a potentially life-saving combination when you need to quickly diagnose issues in production.
require ‘logger’
logger = Logger.new STDOUT
logger.warn “do not want!!!”
def createerror表示还不需要重启服务器的错误。
begin
@group.add_member(current_user)
flash[:notice] = “Successfully joined #{@scene.display_name}”
rescue ActiveRecord::RecordInvalid
flash[:error] = “You are already a member of #{@group.name}”
logger.warn “A user tried to join a group twice. UI should not have allowed it.”
end
redirect_to :back
end
rake log:clear
• The controller and action that were invoked
• The remote IP address of the computer making the request
• A timestamp indicating when the request happened
• The session ID associated with the request
• The hash of parameters associated with the request
• Database request information including the time and the SQL statement executed
• Query cache hit info including time and the SQL statement triggering results from the cache instead of a roundtrip to the database
• Rendering information for each template involved in rendering the view output and time consumed by each
• Total time used in completing the request with corresponding request-per-second figures
• Analysis of the time spent in database operations versus rendering
• The HTTP status code and URL of the response sent back to the client
class XyyTabnav < Tabnav::Base在Tabnav这个plugin的目录下,有个generators文件夹,里面相当于是个demo,模仿着用就行了。
add_tab do
named 'tab_1'
links_to(lambda{ { :controller => 'xxx', :action => 'show', :id => 1 }})
end
add_tab do
named 'tab_2'
links_to(lambda{ { :controller => 'yyy', :action => 'index' }})
end
end
autotest
bash: autotest: command not found
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
source .bashrc
autotest
/还是跟缩进相关。
The forward slash character, when placed at the beginning of a line, wraps all text after it in an HTML comment. For example:
%peanutbutterjelly
/ This is the peanutbutterjelly element
I like sandwiches!
is compiled to:
<peanutbutterjelly>
<!-- This is the peanutbutterjelly element -->
I like sandwiches!
</peanutbutterjelly>
The forward slash can also wrap indented sections of code. For example:
/
%p This doesn't render...
%div
%h1 Because it's commented out!
is compiled to:
<!--
<p>This doesn't render...</p>
<div>
<h1>Because it's commented out!</h1>
</div>
-->
%title
= @title
\- MySite
is compiled to:
<title>
MyPage
- MySite
</title>
从练习关闭某一个感官的知觉开始。比如,盯着一幅画,尝试着不去感受其他所有感官带来的刺激。关闭你的触觉、听觉、嗅觉甚至味觉。坚持两三分钟,如果你意识到你不小心体会到了视觉之外的感官刺激,那就重新开始。总计做上十五分钟。每天做一次,持续一个星期。
随后你要做的是,每个星期换一个感官去关注。比如,下个星期,你练习这个:闭上你的眼睛听音乐,然后开始尝试关闭你的视觉、触觉、嗅觉、和味觉。然后再下个星期再换一个,比如专注嗅觉而关闭其他的感官。
挑出一件你认为最重要的事儿,然后,给自己做个时间表,在未来的一个星期乃至一个月的时间里,每天至少专注与这件事儿2个小时。
你可以参照所谓的时间分割法。比如,你需要在这件事儿上专注2个小时,即120分钟。那你应该把当天的任务分解成6块,而每一块用20分钟完成。你把20分钟当作你专注的基本时间单位,而每个时间单位过后,休息5分钟,想办法犒劳一下自己——喝杯咖啡或者牛奶。在属于休息时间的5分钟之内的最后1分钟,重新振作,尝试着恢复状态之后,进入下一个基本时间单位——另一个20分钟。
在你规划你的时间的时候,你应该明白为了能够完全专注120分钟,你最终需要规划出差不多150分钟左右的时间开销。
如果,一个人不是很懒惰的话,那什么时候开始学都不晚啊!知道自己需要的是什么,真正的学习才开始。
如果一个计划的期限只有一个星期的时候,我是很容易坚持,并且往往可以出色地完成。
随着时间的推移,我竟然可以慢慢把期限延长,两个星期,一个月,甚至竟然可以指定一个季度的计划了!
晚上通常比较安静,做事基本不受打搅。可是,问题在于,早上的时间也通常不会受到干扰啊?
假设你要讲解的事情是A,那么你应该这么做:
1.尝试着把A全部搞清楚;
2.尝试着把A用清晰的逻辑讲解清楚;
3.在自己的脑子里想象一下听众会有怎样的反应(疑点,难点,迷惑之处),尽量去穷尽各种情况;
4.对听众重要的反应做出合理的回应;
5.把这些合理的回应综合到刚才第二步整理出来的内容中;
6.反复这个过程。
# Renders the template for the action "short_goal" within the current controller,
# but without the current active layout
render :action => "short_goal", :layout => false
# Renders the template for the action "long_goal" within the current controller,
# but with a custom layout
render :action => "long_goal", :layout => "spectacular"
a == b #=> true #因为a与b类型相同,id相等,ActiveRecord就认为它们是同一个对象
a.equal?(b) #=> false #因为不是同一个对象
a.eql?(b) #=> false #因为值不相等
rails dummy_app
cd dummy_app
rake rails:freeze:gems
$echo >vendor/rails/activesupport/README
rake doc:rails
def remove_keys(hash, *keys)
new_hash = hash.dup
keys.each {|k| new_hash.delete(k)}
new_hash
end
# Returns a new hash without the given keys.
def except(*keys)
rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
reject { |key,| rejected.include?(key) }
end
# Replaces the hash without only the given keys.
def except!(*keys)
replace(except(*keys))
end
def convert_key(key)像params这种,里面的key存的全都是string,你指定删除symbol的key,如果程序实现直接去删的话,就会不起作用(没有去掉指定的key)
key.kind_of?(Symbol) ? key.to_s : key
end
def except(*keys)运行测试,还是全都通过了,看来测试代码没有覆盖到这种情况。
rejected = keys
reject { |key,| rejected.include?(key) }
end
def test_except
original = { :a => 'x', :b => 'y', :c => 10 }
expected = { :a => 'x', :b => 'y' }
# Should return a new hash with only the given keys.
assert_equal expected, original.except(:c)
assert_not_equal expected, original
# Should replace the hash with only the given keys.
assert_equal expected, original.except!(:c)
assert_equal expected, original
end
def test_except哈哈,测试报错了,看来我们刚才添加的测试代码起作用了,TDD的第一步,即写一段测试,使测试failed,已经完成了。
original = { :a => 'x', :b => 'y', :c => 10 }
expected = { :a => 'x', :b => 'y' }
# Should return a new hash with only the given keys.
assert_equal expected, original.except(:c)
assert_not_equal expected, original
# Should replace the hash with only the given keys.
assert_equal expected, original.except!(:c)
assert_equal expected, original
original = HashWithIndifferentAccess.new(:a => 'x', :b => 'y', :c => 10)
expected = HashWithIndifferentAccess.new(expected)
assert_equal expected, original.except(:c)
end
rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
def except(*keys)晕死,原来就这么简单呀,到处去找不改变hash本身的delete方法,其实reject就是:
reject { |key,| keys.include?(key) }
end
Same as Hash#delete_if, but works on (and returns) a copy of the hsh. Equivalent to hsh.dup.delete_if.
script/about
About your application's environment
Ruby version 1.8.5 (i486-linux)
RubyGems version 0.9.4
Rails version 1.2.5
Active Record version 1.15.5
Action Pack version 1.13.5
Action Web Service version 1.2.5
Action Mailer version 1.3.5
Active Support version 1.4.4
Edge Rails revision 547
Application root /home/xxx/project/
Environment development
Database adapter mysql
Database schema version 3
ruby vendor\rails\railties\bin\rails -v
body, h1, h2, h3, h4, h5, h6, p, ol, ul, form, blockquote {
padding: 0;
margin: 0;
}
h1, h2, h3, h4, h5, h6, pre, code {
font-size: 1em;
}
a {
text-decoration: none;
}
a img {
border: none;
}
def attr_accessor_with_default(sym, default = nil, &block)
raise 'Default value or block required' unless !default.nil? || block
define_method(sym, block_given? ? block : Proc.new { default })
module_eval(<<-EVAL, __FILE__, __LINE__)
def #{sym}=(value)
class << self; attr_reader :#{sym} end
@#{sym} = value
end
EVAL
end
def foo由class << self; attr_reader :#{sym} end 生成:
default
end
def foo所以一旦调用了set方法,前面的get方法被后面的get方法覆盖。
@foo
end
def foo=(value)
@foo = value
end
def attr_accessor_with_default(sym, default = nil, &block)
raise 'Default value or block required' unless !default.nil? || block
define_method(sym, block_given? ? block : Proc.new { default })
module_eval(<<-EVAL, __FILE__, __LINE__)
def #{sym}=(value)
class << self; attr_reader :#{sym} end
@#{sym} = value
# @#{sym} = value # 注释掉该行,使得set方法不赋值,但仍然生成一个新的get方法,并生成名为@#{sym}的实例变量
end
EVAL
end
def test_default_arg
@target.attr_accessor_with_default :foo, :bar
p @instance.foo # 执行set方法前,调用get方法
assert_equal(:bar, @instance.foo)
@instance.foo = 'foo' # 此处赋值为'foo',而非原来的nil
p @instance.foo # 执行set方法后,再调用get方法
# assert_nil(@instance.foo) # 注释掉该行,以免因为我们的修改而使测试出错
end
...:bar
nil...
h = HashWithIndifferentAccess.new #=> {}
h[:a] = "a" #=> "a"
h #=> {"a" => "a"}
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)先给父类的[]=方法和update方法取个别名,然后再覆盖这两个方法。
alias_method :regular_update, :update unless method_defined?(:regular_update)
def []=(key, value)
regular_writer(convert_key(key), convert_value(value))
end
def update(other_hash)
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
self
end
def stringify_keys!; self end测试代码如下:
def symbolize_keys!; self end
def test_stringify_and_symbolize_keys_on_indifferent_preserves_hash
h = HashWithIndifferentAccess.new
h[:first] = 1
h.stringify_keys!
assert_equal 1, h['first']
h = HashWithIndifferentAccess.new
h['first'] = 1
h.symbolize_keys!
assert_equal 1, h[:first]
end
def test_stringify_and_symbolize_keys_on_indifferent_preserves_hash
h = HashWithIndifferentAccess.new
h[:first] = 1
h.stringify_keys!
assert_equal 1, h['first']
h = HashWithIndifferentAccess.new
h['first'] = 1
h.symbolize_keys!
assert_not_equal :first, h.index(1)
# assert_equal 1, h[:first]
end
def default(key = nil)它覆盖了default方法,而ruby实现里[]方法会去调用default方法。具体的ruby底层实现机制我并不了解,只是通过改源代码和其测试代码,发现了default方法跟[]方法相关。
if key.is_a?(Symbol) && include?(key = key.to_s)
self[key]
else
super
end
end
Close All Alt + B W (custom) or Shift + Ctrl + W
Max/Min Editor Alt + 1 (custom) or Ctrl + 1 (custom)
Open Resource Alt + 2 (custom) or Ctrl + 2 (custom)
Next Editor Alt + 3 (custom)
Search Alt + 4 (custom)
Switch to test Alt + 5 (custom)
Switch to model Alt + 6 (custom)
Switch to view Alt + 7 (custom)
Switch to contraller Alt + 8 (custom)
Save Alt + S (custom)
Close Alt + W (custom)
Undo Alt + E (custom)
Redo Alt + R (custom)
Line Up Alt + I (custom)
Line Down Alt + K (custom)
Previous Column Alt + J (custom)
Next Column Alt + L (custom)
Line Start Alt + H (custom)
Line End Alt + ; (custom)
Page UP Alt + U (custom)
Page Down Alt + N (custom)
Previous Word Alt + O (custom)
Next Word Alt + P (custom)
Text Start Alt + 9 (custom) or Alt + B I (custom)
Text End Alt + 0 (custom) or Alt + B K (custom)
Duplicate Lines Alt + T (custom)
Cut Lines Alt + Y (custom)
Delete Lines Alt + D (custom)
Move Line Up Alt + ↑ (custom)
Move Line Down Alt + ↓ (custom)
Select Line Start Alt + [ (custom) or Alt + B J (custom) or Ctrl + H (custom)
Select Line End Alt + ] (custom) or Alt + B L (custom) or Ctrl + ; (custom)
Select Previous Column Alt + < (custom) or Ctrl + J (custom) Select Next Column Alt + > (custom) or Ctrl + L (custom)
Select Line Up Ctrl + I (custom)
Select Line Down Ctrl + K (custom)
Select Next Word Alt + G (custom)
Scroll Line Up Ctrl + ↑
Scroll Line Down Ctrl + ↓
Toggle Comment Alt + M (custom)
Collapse Alt + Q (custom)
Expand Alt + A (custom)
Go To Line Alt + B G (custom) or Ctrl + G (custom)
Cut Alt + X (custom) or Ctrl + X
Copy Alt + C (custom) or Ctrl + C
Paste Alt + V (custom) or Ctrl + V
Show View Alt + B N (custom)
Activate Editor Alt + B M (custom) or F12
=> j(Alt + F)
↑ => ↑
↓ => ↓
for i in (m..n) do保存为tm.rb,将m和n换成你要查找的范围,如32..2000或8000..10000,然后在命令行里运行:
puts "<span>&\##{i};</span>"
end
ruby tm.rb > temp.html
%(<span class="normal"> </span><span class="keyword">def</span>).sub!(/(<span class="normal">)(.*)(<\/span>)/) {|s| puts s}
=> <span class="normal"> </span><span class="keyword">def</span>
%(<span class="normal"> </span><span class="keyword">def</span>).sub!(/(<span class="normal">)(.*?)(<\/span>)/) {|s| puts s}
=> <span class="normal"> </span>
./configure
make
sudo make install
如果不能编译的话,就要先安装编译环境:sudo apt-get install build-essential
和boost regex库sudo apt-get install libboost-regex*
keyword = "__FILE__|and|def|end|in|or|self|unless",
"__LINE__|begin|defined?|ensure|module|redo|super|until",
"BEGIN|break|do|false|next|rescue|then|when",
"END|case|else|for|nil|retry|true|while",
"alias|class|elsif|if|not|return|undef|yield"
keyword = "defined?"
comment start "#"
symbol = ':[a-zA-Z0-9_]+'
variable = '\$[a-zA-Z_][a-zA-Z0-9_]*',
'@@[a-zA-Z_][a-zA-Z0-9_]*',
'@[a-zA-Z_][a-zA-Z0-9_]*'
number = '(?<![\w\.])([1-9](_?[0-9])*|0)(?![\w\.])',
number = '(?<![\w\.])([1-9](_?[0-9])*|0)(?![\w\.])',
'(?<![\w\.])(( (\d(_?\d)*)?\.\d(_?\d)* | \d(_?\d)*\. ) | ( (\d(_?\d)*|(\d(_?\d)*)?\.\d(_?\d)*|\d(_?\d)*\.)[eE][+-]?\d(_?\d)* ))(?![\w\.])',
'(?<![\w\.])0[0-7](_?[0-7])*(?![\w\.])',
'(?<![\w\.])0[dD][0-9](_?[0-9])*(?![\w\.])',
'(?<![\w\.])0[xX][0-9A-Fa-f](_?[0-9A-Fa-f])*(?![\w\.])',
'(?<![\w\.])0[bB][01](_?[01])*(?![\w\.])'
regexp delim "/" "/" escape "\\" multiline
regexp delim "%r{" "}" escape "\\" multiline
string delim "'" "'" escape "\\" multiline
string delim "\"" "\"" escape "\\" multiline
string delim "%{" "}" escape "\\" multiline
string delim "%w(" ")" escape "\\" multiline
body { background-color: black; color: white; }
.keyword { color: #DE9309; font-weight: bold; }
.string { color: #00FF00; font-family: monospace; }
.regexp { color: #0000FF; }
.comment { color: #AB50D6; font-style: italic; }
.number { color: #0080FF; }
.symbol { color: #3F92B7; }
.variable { color: #FF0000; }
source-highlight -s ruby -f html -i demo.rb -o demo.html --css ruby_highlight.css --lang-def rb.lang
(天啊,source-highlight,16个字符的命令,真是少见地长。)/* for code highlight */
.code_bgcolor {
background-color:#E5E5E5;
}
.keyword { color: #DE9309; font-weight: bold; }
.string { color: #00DF00; font-family: monospace; }
.regexp { color: #0000FF; }
.comment { color: #AB50D6; font-style: italic; }
.number { color: #0080FF; }
.symbol { color: #3F92B7; }
.variable { color: #FF0000; }
/* for command line */
.post .cmd {
background-color:#000000;
padding: 10px;
margin: 7px 0px 7px 0px;
}
.cmd_failed { color:#ff0000; }
.cmd_normal { color:#00ff40; }
/* for quote */
.post .quote {
border: 1px solid #BFBFBF;
margin: 7px 0px;
padding:5px 20px;
}
<p class="cmd"><span class="cmd_normal">Oh_Yes</span></p>
<p class="cmd"><span class="cmd_failed">Oh_No</span></p>
Oh_Yes
Oh_No
<pre class="quote code_bgcolor"><tt>
<span class="keyword">def<span>
</tt></pre>
def
<p class="quote">some_text</p>
some_text
`source-highlight -s ruby -f html -i r.rb -o r.html --css ruby_highlight.css --lang-def rb.lang`
sleep 1
code_start = '<pre class="quote code_bgcolor">'
File.open("r.html").each do |line|
line.gsub!(/<pre>/) {|s| s = code_start if s}
line.gsub!(/(<span class="normal">)(.*?)(<\/span>)/) {$2}
puts line
end
ruby blog_scripts.rb > r2.html
哈哈,去r2.html把相应的HTML拷过来就可以了source-highlight -s ruby -f html -i demo.rb -o demo.html --style-file rb.style --lang-def rb.lang
这次生成的HTML就在标签的style属性里直接写CSS了。在网页设计上这是一种很糟糕的方式,很不DRY(Don't Repeat Yourself),而且用了很多已经不推荐使用的font标签,整个HTML的也变大了,膨胀了。class User这样居然作者就说一切都搞定了,很明显assign_role方法什么也没做过,而且从这步直接重构就跳到了:
def in_role?(role)
role == "assigned role"
end
def assign_role(role)
end
end
class User感觉逻辑上有断层。记忆中他们在RubyConf上演示的demo逻辑很完整,跟这个稍有不同。
def in_role?(role)
role == @role
end
def assign_role(role)
@role = role
end
end
describe User do注意,这里只是描述了dave的某个行为,根本没有管究竟有没有dave这个object,这是后面的事。
it "should be in a role to which it is assigned" do
dave.assign_role("speaker")
dave.should be_in_role("speaker")
end
end
"undefined local variable or method 'dave' ... "
这里就是BDD的精髓之一了,描述完了后,运行测试,系统自然会告诉你,接下来应该做什么。describe User do这次的失败信息不同了:
it "should be in a role to which it is assigned" do
dave = User.new
dave.assign_role("speaker")
dave.should be_in_role("speaker")
end
end
"undefined method 'assign_role' ... "
class User失败信息:
def assign_role
end
end
"wrong number of arguments (1 for 0)"
哈哈,简直“懒”到了极致,你系统说没有方法,那我就给你个空的方法,任何多余的事我都不做。其实是“简”到了极致,跟描述无关的功能,我为什么要去实现呢?class User失败信息:
def assign_role(role)
end
end
"undefined method 'in_role?' ... "
class User失败信息:
def assign_role(role)
end
def in_role?
end
end
"wrong number of arguments (1 for 0)"
这种迭代的步伐也小到了极致。class User终于迎来跟描述相关的失败信息了:
def assign_role(role)
end
def in_role?(role)
end
end
"expected in_role?("speaker") to return true, got nil"
dave说通常这时我们会用个非常简单,甚至有点愚蠢的做法来让测试通过。class User终于通过了:
def assign_role(role)
end
def in_role?(role)
true
end
end
"1 example, 0 failures"
到目前为止,我们都没看过最初定义的行为描述,而是一直照着系统告诉我们的信息在做。系统就像一个不知疲倦的“客户”,当它把需求“背下来”后(我们描述完行为后),它就会不断地告诉你接下来该做什么,以及你刚才做的是否符合它的要求。describe User do理所当然地又失败了(这里如果没有失败的话,理论上是有问题的,因为客户新提的需求,程序没做任何改动居然就能满足了,要么是以前程序员太多事,自作主张加了些功能,要么是需求提得不对,跟以前的需求重复了):
it "should be in a role to which it is assigned" do
dave = User.new
dave.assign_role("speaker")
dave.should be_in_role("speaker")
end
it "should not be in a role to which it was not assigned" do
aslak = User.new
aslak.should_not be_in_role("speaker")
end
end
"expected in_role?("speaker") to return false, got true"
哈哈,报应来了吧,叫你蠢,直接硬编码true,现在客户要false了。class User又通过了:
def assign_role(role)
@role = role
end
def in_role?(role)
@role == role
end
end
"2 examples, 0 failures"
这次我们没有做任何蠢事,我们真正实现了功能,同时满足了那两个描述。You are allowed to put anything you want in your template, since it just becomes an HTML file like any other once it is published. That means that Blogger doesn't specifically disallow any HTML or CSS, but it also means that it's up to you to make sure that what you use is correct and supported by your browser.
经测试,CSS的浏览器兼容性没有问题。Windows XP下:Firefox 2.0, IE 6, IE 7 都没问题。Ubuntu 7.10下:Firefox 2.0, Opera 9.23都没问题,ies4linux少数汉字无法正常显示,但CSS布局一切正常,那是软件本身的问题,不是CSS不兼容。对于初次切换到 Linux 系统的朋友来说,如果想要从命令行界面执行查找文件的任务的话,那么,locate 和 find 是两个需要了解的命令。虽说这两个命令都可以满足查找文件的操作,不过却是各有所长,在选择上不妨兼而用之。
sudo updatedb
来手动更新。 假如我想要在系统中查找一个名为 linux.html 的文件,那么可以这样执行命令:locate linux.html
。locate 搜索文件的速度很快,一会儿就会把结果列出来。locate 有一个十分有用的选项 -r,它可以让你在搜索文件时使用正则表达式。
find 位置 -name 文件名称
。例如,我要在 / 这个根目录中查找 linux.html 文件,可以执行 find / -name linux.html
。你除了可以按文件名称来使用 find 查找文件外,也可以根据文件大小(通过 -size n 选项指定)、时间(如 -atime n 表示查找 n 天前访问过的文件)来搜索文件。 此外,find 命令同样支持在搜索文件时使用正则表达式,你只需指定 -regex 选项即可。
值得注意的是,对于 locate 与 find 这两个命令的解说远非这篇小文所能满足。关于这两个命令的更加详细的用法,你可能需要通过 man locate 或 man find 查询。
原文见:http://hi.baidu.com/nfubuntu/blog/item/b4fd33f359911050342acc70.htmlSOAP以前代表Simple Object Access Protocol(简单对象访问协议)。当人们无法忍受这种反讽,这种字母缩写的解释被丢弃了,而SOAP就只是个名字了。
----------------------------
SOAP once stood for Simple Object Access Protocol. When folks could no longer stand the irony, the acronym was dropped, and now SOAP is just a name.