Copy Source | Copy HTML<br/>get "/hello" do <br/> "Hello World" <br/> end <br/>
(see www.sinatrarb.com/intro.html - approx. transl . )Copy Source | Copy HTML<br/>@get( '/hi' )<br/> def hello ():<br/> return "Hello World" <br/> <br/> def hello () -> "/hi" :<br/> return "Hello World" <br/>
Copy Source | Copy HTML<br/> def append (location, data)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> File . open (path, "a" ) do |file|<br/> file. puts YAML .dump(data)<br/> end <br/> <br/> return data<br/> end <br/>
File.open
File.open
takes a block as a parameter. It opens a new file (in the “append” mode) and transfers the open file to the block. When he finishes, Ruby closes the file. In addition, Ruby does not just close the file, it guarantees that the File will be closed, even if block execution ends with an exception. Let's look at the File implementation in Rubinius :Copy Source | Copy HTML<br/> def self . open (*args)<br/> io = new *args<br/> <br/> return io unless block_given?<br/> <br/> begin <br/> yield io<br/> ensure <br/> begin <br/> io.close unless io.closed?<br/> rescue StandardError <br/> # nothing, just swallow them. <br/> end <br/> end <br/> end <br/>
Copy Source | Copy HTML<br/> # <br/> def append (location, data)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> begin <br/> file = File . open (path, "a" )<br/> file. puts YAML .dump(data)<br/> ensure <br/> file.close<br/> end <br/> <br/> return data<br/> end <br/>
ensure
even when an exception occurs inside a block, the programmer can be sure that Ruby will execute the terminating logic hidden inside the method.Copy Source | Copy HTML<br/> def write (location, data)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> File . open (path, "w" ) do |file|<br/> return false if Digest::MD5.hexdigest(file.read) == data.hash<br/> file. puts YAML .dump(data)<br/> end <br/> <br/> return true <br/> end <br/>
write
method, but Ruby still calls ensure
to close the file.Copy Source | Copy HTML<br/> def write (location, data)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> File . open (path, "w" ) do |file|<br/> raise Return. new ( false ) if Digest::MD5.hexdigest(file.read) == data.hash<br/> file. puts YAML .dump(data)<br/> end <br/> <br/> return true <br/> rescue Return => e<br/> return e.object<br/> end <br/>
where Return is Return = Struct.new(:object)
.rescue
or ensure
already being used, avoiding puzzling combinations.super
inside a block. Imagine that the write
method was overridden in a subclass, and the same parent class method simply takes the raw data from the file and writes it to the log.Copy Source | Copy HTML<br/> def write (location, data)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> File . open (path, "w" ) do |file|<br/> file_data = file.read<br/> super (location, file_data)<br/> return false if Digest::MD5.hexdigest(file_data) == data.hash<br/> file. puts YAML .dump(data)<br/> end <br/> <br/> return true <br/> end <br/>
Copy Source | Copy HTML<br/> def write (location, data)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> this = self <br/> File . open (path, "w" ) do |file|<br/> file_data = file.read<br/> <br/> # Ruby <br/> # non-local-super <br/> this. super . write (location, file_data)<br/> raise Return. new ( false ) if Digest::MD5.hexdigest(file_data) == data.hash<br/> file. puts YAML .dump(data)<br/> end <br/> <br/> return true <br/> rescue Return => e<br/> return e.object<br/> end <br/>
yield
on a block obtained by a method inside another block. Imagine that the write
method is invoked with a block that chooses which data to use depending on whether the file is executable:Copy Source | Copy HTML<br/> def write (location)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> File . open (path, "w" ) do |file|<br/> file_data = file.read<br/> super (location)<br/> data = yield file<br/> return false if Digest::MD5.hexdigest(file_data) == data.hash<br/> file. puts YAML .dump(data)<br/> end <br/> <br/> return true <br/> end <br/>
Copy Source | Copy HTML<br/>write( "/path/to/file" ) do |file|<br/> if file.executable?<br/> "#!/usr/bin/env ruby\nputs 'Hello World!'" <br/> else <br/> "Hello World!" <br/> end <br/> end <br/>
Copy Source | Copy HTML<br/> def write (location, block)<br/> path = Pathname . new (location)<br/> raise "Location does not exist" unless path.exist?<br/> <br/> this = self <br/> File . open (path, "w" ) do |file|<br/> file_data = file.read<br/> <br/> # Ruby, <br/> # non-local-super <br/> this. super . write (location, file_data)<br/> data = block. call (file)<br/> raise Return. new ( false ) if Digest::MD5.hexdigest(file_data) == data.hash<br/> file. puts YAML .dump(data)<br/> end <br/> <br/> return true <br/> rescue Return => e<br/> return e.object<br/> end <br/>
Copy Source | Copy HTML<br/> def write (file)<br/> file_data = file.read<br/> super (file)<br/> data = yield file<br/> return false if Digest::MD5.hexdigest(file_data) == data.hash<br/> file. puts YAML .dump(data)<br/> return true <br/> end <br/>
Copy Source | Copy HTML<br/> def index <br/> @people = Person.find(:all)<br/> <br/> respond_to do | format |<br/> format .html # default action is render <br/> format .xml { render :xml => @people.xml }<br/> end <br/> end <br/>
Copy Source | Copy HTML<br/> def index <br/> @people = Person.find(:all)<br/> <br/> respond_to do | format |<br/> format .html { redirect_to (person_path(@people.first)) and return }<br/> format .xml { render :xml => @people.xml }<br/> format .json { render :json => @people.json }<br/> end <br/> <br/> session[:web_service] = true <br/> end <br/>
return
, yield
and super
together can be seen extremely rarely. Ruby programmers typically use one or more of these constructs inside blocks, simply because their use seems natural.synchronized
:Copy Source | Copy HTML<br/> class Example {<br/> final Lock lock = new Lock();<br/> <br/> void example() {<br/> synchronized( lock ) {<br/> // <br/> }<br/> }<br/>} <br/>
try/finally
prior to Python version 2.5, when a special language function was added to handle the try/finally
idiom:Copy Source | Copy HTML<br/> class Example :<br/> # <br/> def example (self):<br/> lock.acquire()<br/> try :<br/> ... access shared resource<br/> finally :<br/> lock.release() # , <br/> <br/> # <br/> def example (self):<br/> with lock:<br/> ... access shared resource <br/>
with
must implement a special protocol (including the __enter__
and __exit__
methods), so the with
expression cannot be used as general purpose and lightweight Ruby blocks.Copy Source | Copy HTML<br/> class Example <br/> @@lock = Mutex .new<br/> <br/> def example <br/> @@lock.synchronize do <br/> # <br/> end <br/> end <br/> end <br/>
synchronize
is a normal Ruby method. The original version, written in pure Ruby, looks like this :Copy Source | Copy HTML<br/> def synchronize <br/> lock<br/> begin <br/> yield <br/> ensure <br/> unlock<br/> end <br/> end <br/>
synchronize
will work correctly.Copy Source | Copy HTML<br/> File . open (path, “a”) do |file|<br/> # … <br/> end <br/>
at:Copy Source | Copy HTML<br/>path. open (“a”) do |file|<br/> # … <br/> end <br/>
Copy Source | Copy HTML<br/> def a <br/> yield <br/> end <br/> a { return 0 } # => LocalJumpError: unexpected return <br/> <br/> def c <br/> yield <br/> end <br/> <br/> def b <br/> c { return 1 }<br/> end <br/> b # => 1 <br/> <br/> def d <br/> lambda { return 2 }.call<br/> end <br/> d # => 2 <br/>
Source: https://habr.com/ru/post/86882/
All Articles