性能估计没有差别。一旦执行了外部方法,内部方法就会被定义在类中,整个类均可见,不会因为外部方法执行完毕而 undef 内部方法。跟直接定义在类中没有差别,反而显得奇怪。你还不如内部用 lambda
[]=
是另一个方法,a[3]='x'是 a.[]=(3,'x') 的语法糖,而不是先调用[]
后再用等号赋值。
只要 a 和 b 是不同的对象,你这个需求就很难实现。想知道什么情况下需要实现这样的效果? Array#slice和Array#[]没区别,Array.instance_method(:[])==Array.instance_method(:slice) 返回 true。其实看文档就知道了
同楼上。不过 codewar 上有个怪风气,就是偏爱简短的代码,而非清晰的代码。有时候要很熟悉 API 才能看懂靠前的解法,不过正好用来熟悉 API
都是比较靠谱实际的问题,没有整算法之类高大上的东西。
不过楼主发视频不给面试者名字、视频打个马赛克么
搞调试还要在 production 下玩。。。如果你没有源码部署经验,会踩很多坑 预编译 RAILS_ENV=production bin/rails assets:precompile 之后再配置 nginx,具体配置内容谷歌
你确定要运行的 production 环境而不是 development?我怀疑你是想整开发环境但误以 production 启动了
production 环境下应该是先把静态文件编译到 public 目录下,再用 web 服务器来伺服静态文件。具体看看你的 production.log
楼主可能想考察面试者的动手能力和自学能力。 个人经验是不难,我还在做测试工程师的时候就是这么搭的环境,不过当时还是踩了很多坑
应该不能哦,watir 不是基于 http 的。你的原始需求是啥
break
牛啤,必须围观
[] 这东西你可以理解为取数组元素,但在某些情况下又是调用方法 (或函数),这就是设计的不一致性
看来你并不知道“多态”。。。
我开始认为上面很多人的回复 (包括我的) 你其实并没有完全看懂。
那么 def 定义的方法为什么不能被一个变量接受呢
只要拿到这个方法的引用,自然将其赋值给变量。js 里 obj.foo 就能拿到函数引用,加个小括号,obj.foo() 就表示函数调用,而ruby 中小括号并无特殊语义,obj.foo 直接表示方法调用,method(:foo) 就是获取该方法的引用,通过 call 来调用,其它 [] 等写法只是 call 的别名。我觉得问题就在于小括号这里,一旦习惯无小括号的写法,写起来就十分的潇洒。如果赋予小括号语义,那就不能兼容当前几乎所有的 ruby 代码
其实他们都是方法不是吗?
严格的答案是:不是。有的是方法,有的只是函数。我猜你没有仔细想过我上个回复中贴的那段代码需求
那么设计可以简化一下,简化之后其实就是函数式编程了,传递方法,闭包,甚至回调函数
传递闭包一直都可以实现,只是未按照你想要的方式实现而已。还是那句话,你把 js 当标准,自然可以说 ruby 不标准。单单说“函数式编程”这样的概念并无太大的实际意义,重要的是解决实际问题。而且你一直在顶级作用域搞,没有考虑 OO,实在是把问题场景想得太简单了
比如你说的 block 和 proc 其实都是可以写成 def 定义的方法
我没有说过 block 和 proc 可以写成 def 定义的方法。。。proc 返回是个对象。
你依然没有弄清 def、proc 的区别,甚至没有严格区分“函数 (function)”和“方法 (method)”的概念。 如果你认为 proc 和 def 是一类东西,尝试在不破坏封装的情况下用 proc 来重写下面的代码
class Person
def initialize(str); @name = str; end
def introduce
"My name is #{@name}"
end
end
你现在认为 proc、lambda 之类的是过度设计,我个人觉得,一是因为你当前没有熟练掌握 ruby,缺少对 ruby 的“语感”;二是因为你先入为主,把 js 的相关实现当做标准,自然就衬托出了 ruby 的不标准
楼主勇气可嘉。
def,define_method,proc,lambda 这几个,def 是关键字,用于定义方法,隔离作用域; define_method 也用于定义方法,但他本身就是个方法,因此可以通过传参来动态定义方法,扁平化作用域; proc 是对象化的 block(block 更接近于匿名函数的概念),lambda 是特殊的 proc,在 return 和参数上与 proc 有区别。
整个语言就是参数可以是函数,返回也可以是函数
传个 block,返回 proc,不就是这个么。
至于装饰器,可以用元编程自己封个方法去实现,aop 还有现成的 gem
另外。你可能还不知道 ruby 有 method 对象和 unbound_method 对象这样的东西。。。
你觉得这些东西太乱,其实是因为你新摄入太多 ruby 概念,又没有完全理解,写的 ruby 代码又太少。你现在最最重要的不是给官方提建议,而是多写代码
祝楼主学习愉快
关键字:作用域门
想实现闭包请使用 Proc
def method1()
param = []
method2 = proc { |x| param.push(x) }
return method2
end
f = method1
f.call(10)
问题在于读取的长度限制,r.read(2048) 只会在读取够了 2048 个字符时 (或者遇到了 eof) 才会返回,如果你改成 r.read(1),就会立即输出了。实际上一般的需求都是逐行输出,不用 read 而用 gets
r, w = IO.pipe
if fork
w.close
until r.eof? do
input = r.gets
puts input
end
r.close
Process.wait
else
r.close
loop do
str = gets
break if str.chomp == 'exit'
w << str
end
w.close
end
原因找到了,除了 rails 的 fresh_when 有处理条件请求的逻辑外,rack 的 condition_get.rb 也有相关逻辑
Rails::Rack::Logger 先行打印日志,此时 status 为 200。
在 rack 2.2 的版本,rack/lib/rack/conditional_get.rb 中的 fresh?方法逻辑是优先判断 if-none-match,只要 if-none-match 和 etag 匹配,就不再处理 If-Modified-Since,直接返回 true。当 fresh?为 true 时 call 方法会将 200 的 status 重写为 304。因此服务器日志中看到是 200,实际客户端收到是 304
而在 rack 2.1 的版本,conditional_get.rb 中的 fresh?会判断 if-none-match 和 if-modified-since,都满足条件才会返回 true。因此在较老版本的 rails(rack 低于 2.2) 中不会遇到帖子中描述的问题。
#rack/conditional_get.rb
def call(env)
case env[REQUEST_METHOD]
when "GET", "HEAD"
status, headers, body = @app.call(env)
headers = Utils::HeaderHash.new(headers)
if status == 200 && fresh?(env, headers)
status = 304
headers.delete(CONTENT_TYPE)
headers.delete(CONTENT_LENGTH)
original_body = body
body = Rack::BodyProxy.new([]) do
original_body.close if original_body.respond_to?(:close)
end
end
[status, headers, body]
else
@app.call(env)
end
end
#rack 2.1
def fresh?(env, headers)
modified_since = env['HTTP_IF_MODIFIED_SINCE']
none_match = env['HTTP_IF_NONE_MATCH']
return false unless modified_since || none_match
success = true
success &&= modified_since?(to_rfc2822(modified_since), headers) if modified_since
success &&= etag_matches?(none_match, headers) if none_match
success
end
#rack 2.2
def fresh?(env, headers)
# If-None-Match has priority over If-Modified-Since per RFC 7232
if none_match = env['HTTP_IF_NONE_MATCH']
etag_matches?(none_match, headers)
elsif (modified_since = env['HTTP_IF_MODIFIED_SINCE']) && (modified_since = to_rfc2822(modified_since))
modified_since?(modified_since, headers)
end
end
谢谢大佬的认真回复。nginx 一直是关闭的。
etag 的变化其实不在这个问题讨论的范畴了。etag 一旦不一致,服务端确实会返回 200,客户端也会收到 200。
Rack::ConditionalGet 会比较 etag 和 last_modifed. 如果 etag 和请求的 If-None-Match 匹配的话,它会自动帮你改为 304
之前看过这一段源码
def fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, template: nil)
weak_etag ||= etag || object unless strong_etag
last_modified ||= object.try(:updated_at) || object.try(:maximum, :updated_at)
if strong_etag
response.strong_etag = combine_etags strong_etag,
last_modified: last_modified, public: public, template: template
elsif weak_etag || template
response.weak_etag = combine_etags weak_etag,
last_modified: last_modified, public: public, template: template
end
response.last_modified = last_modified if last_modified
response.cache_control[:public] = true if public
head :not_modified if request.fresh?(response)
end
def fresh?(response)
last_modified = if_modified_since
etag = if_none_match
return false unless last_modified || etag
success = true
success &&= not_modified?(response.last_modified) if last_modified
success &&= etag_matches?(response.etag) if etag
success
end
fresh_when 的最后一行的逻辑就是返回 304 的响应,但需要同时满足 etag 和 If-Modified-Since 这两项条件才行。当我的 if-modified-since 使用的是较老的时间时,当然不会 head :not_modified。日志中看到 render 200,但客户端显示了 304。
我之前怀疑客户端收到的是 200,但由于某种逻辑 (比如返回的 etag 没有改变) 显示为 304,于是用 charles 抓包,但抓包结果就显示 304。
我刚才又用 rails6.0.2.2 新建了一个纯净的项目,依然遇到了这个问题。但在一个不纯净的 rails6.0.2 版本上就没有遇到此问题
兄弟你还是没明白我的问题。论坛里相关的帖子我都看过了
当请求的资源没更新时,在 stale? @subjects
时就会返回 304,客户端收到的也是 304,这是正常的,使用了客户端缓存。
但资源更新后,用同样的请求,会执行render plain: 'stale', status: 200
,从日志看,服务器返回的是 200。到这一步为止也是正常的。问题时客户端收到的不是 200,而是 304。
而将 render 中的 status 改成 201、202、203 之类的,同样的请求,客户端就能正常显示 201、202、203,而非 304
感叹一哈撒。8 年人生大起大落,回头一看,才二十六七岁。人生经验赶超我辈啊
我知道 304 是使用客户端缓存,关键是我的服务器的 response status 是 200,为什么到了客户端就成了 304
刺激!8 年过去了也比我年轻
俺们不相信,哪的培训起步 12k
专业! 明白了,2.7 中,单例类的类变量的查询不在 receivers' ancestors 上了,而以前版本的查询又有 bug。
确实 。2.7 里修正了这个行为,只能通过A.singleton_class.singleton_class.class_variables
来获取了
居然行了,但是想不通原因
额 ,我想错模型了
一楼的想法和我一样。应该把中间表作为查询的主表。
我注意到另一个问题,最开始@topics = @user.topics,这里查出的所有的 topic 是@user的了,那么视图中 topic.topic_users 查出来的结果自然也应该是@user的,为什么还需要 with_user(@user.id) 来再次限定。我在想去掉这个 with_user 后,配合原来的 includes 会不会还有 N+1