В Java все находится в форме класса.
Если вы хотите использовать любой объект, тогда у вас есть две фазы:
Пример:
Object a;
a=new Object();
То же самое для концепции массива
Item i[]=new Item[5];
i[0]=new Item();
Если вы не дают секцию инициализации, тогда возникает NullpointerException
.
От Ruby 1.9 Proc# === псевдоним к Proc#call, что означает, что объекты Proc могут использоваться в случае, если операторы как так:
def multiple_of(factor)
Proc.new{|product| product.modulo(factor).zero?}
end
case number
when multiple_of(3)
puts "Multiple of 3"
when multiple_of(7)
puts "Multiple of 7"
end
Эти отправляют () , метод является методом общего назначения, который может использоваться на любом Классе или Объекте в Ruby. Если не переопределенный, отправьте (), принимает строку и называет название метода, строка которого оно передается. Например, если пользователь нажмет кнопку “Clr”, строка вЂpress_clear’ будет отправлена в отправление (), метод и вЂpress_clear’ метод назовут. Отправление () метод допускает забавный и динамический способ вызвать функции в Ruby.
%w(7 8 9 / 4 5 6 * 1 2 3 - 0 Clr = +).each do |btn|
button btn, :width => 46, :height => 46 do
method = case btn
when /[0-9]/: 'press_'+btn
when 'Clr': 'press_clear'
when '=': 'press_equals'
when '+': 'press_add'
when '-': 'press_sub'
when '*': 'press_times'
when '/': 'press_div'
end
number.send(method)
number_field.replace strong(number)
end
end
я говорю больше об этой функции в Ведущая блог Обувь: Простое-Calc Приложение
Одурачьте некоторый класс или модуль, говоря, что это потребовало чего-то, чего это действительно не потребовало:
$" << "something"
Это полезно, например, при требовании, который по очереди требует B, но нам не нужен B в нашем коде (и A не будет использовать его ни один через наш код):
, Например, Backgroundrb bdrb_test_helper requires
'test/spec'
, но Вы не используете его вообще, таким образом, в Вашем коде:
$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
используйте что-либо, что отвечает ===(obj)
для сравнений случая:
case foo
when /baz/
do_something_with_the_string_matching_baz
when 12..15
do_something_with_the_integer_between_12_and_15
when lambda { |x| x % 5 == 0 }
# only works in Ruby 1.9 or if you alias Proc#call as Proc#===
do_something_with_the_integer_that_is_a_multiple_of_5
when Bar
do_something_with_the_instance_of_Bar
when some_object
do_something_with_the_thing_that_matches_some_object
end
Module
(и таким образом Class
), Regexp
, Date
, и много других классов определяют метод экземпляра: === (другой), и может все использоваться.
Благодаря Farrel для напоминания Proc#call
искажаемый как Proc#===
в Ruby 1.9.
Большое волшебство, которое Вы видите в Rubyland, имеет отношение к метапрограммированию, которое просто пишет код, который пишет код для Вас. Ruby attr_accessor
, attr_reader
, и attr_writer
является всем простым метапрограммированием, в этом они создают два метода в одной строке, после стандартного шаблона. Направляющие делают много метапрограммирования с их методами управления отношений как has_one
и belongs_to
.
, Но довольно просто создать Ваши собственные приемы метапрограммирования с помощью class_eval
для выполнения динамично записанного кода.
следующий пример позволяет интерфейсный объект форвардам определенные методы внутреннему объекту:
class Wrapper
attr_accessor :internal
def self.forwards(*methods)
methods.each do |method|
define_method method do |*arguments, &block|
internal.send method, *arguments, &block
end
end
end
forwards :to_i, :length, :split
end
w = Wrapper.new
w.internal = "12 13 14"
w.to_i # => 12
w.length # => 8
w.split('1') # => ["", "2 ", "3 ", "4"]
метод Wrapper.forwards
берет символы для названий методов и хранит их в эти methods
массив. Затем для каждого из данных, мы используем define_method
для создания нового метода, задание которого он должен отправить сообщению вперед, включая все аргументы и блоки.
А большой ресурс для проблем метапрограммирования Почему "Наблюдение Lucky Stiff Метапрограммирования Очевидно" .
Peter Cooper имеет хороший список из приемов Ruby. Возможно, мой фаворит его позволяет и единственным объектам и наборам быть перечисленными. (Таким образом, рассматривайте необъект коллекции как набор, содержащий просто тот объект.) Это похоже на это:
[*items].each do |item|
# ...
end
Не знайте, насколько скрытый это, но я нашел его полезным при необходимости сделать Хеш из одномерного массива:
fruit = ["apple","red","banana","yellow"]
=> ["apple", "red", "banana", "yellow"]
Hash[*fruit]
=> {"apple"=>"red", "banana"=>"yellow"}
Один прием, который я люблю, должен использовать нащельную рейку (*
) расширитель на объектах кроме Массивов. Вот пример на соответствии регулярного выражения:
match, text, number = *"Something 981".match(/([A-z]*) ([0-9]*)/)
Другие примеры включают:
a, b, c = *('A'..'Z')
Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom
Одна из прохладных вещей о рубине - то, что можно назвать методы и выполнить код в местах, которые другие языки осудили бы, такой как в методе или определениях классов.
, Например, для создания класса, который имеет неизвестный суперкласс до времени выполнения, т.е. случаен Вы могли сделать следующее:
class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample
end
RandomSubclass.superclass # could output one of 6 different classes.
Это использует 1.9 Array#sample
метод (в 1.8.7-единственном, см. Array#choice
), и пример довольно изобретен, но Вы видите питание здесь.
Другим прохладным примером является способность поместить значения параметров по умолчанию, которые не фиксируются (как другие языки, часто требуют):
def do_something_at(something, at = Time.now)
# ...
end
, Конечно, проблема с первым примером состоит в том, что он оценен во время определения, не время вызова. Так, как только суперкласс был выбран, это остается что суперкласс для остатка от программы.
Однако во втором примере, каждый раз, когда Вы звоните do_something_at
, at
, переменная будет временем, когда метод назвали (хорошо, очень очень близко к нему)
Другая крошечная функция - преобразовывает Fixnum
в любую основу до 36:
>> 1234567890.to_s(2)
=> "1001001100101100000001011010010"
>> 1234567890.to_s(8)
=> "11145401322"
>> 1234567890.to_s(16)
=> "499602d2"
>> 1234567890.to_s(24)
=> "6b1230i"
>> 1234567890.to_s(36)
=> "kf12oi"
И поскольку Huw Walters прокомментировал, преобразовывание другого пути так же просто:
>> "kf12oi".to_i(36)
=> 1234567890
Загрузите источник Ruby 1.9 и выпуск make golf
, тогда можно сделать вещи как это:
make golf
./goruby -e 'h'
# => Hello, world!
./goruby -e 'p St'
# => StandardError
./goruby -e 'p 1.tf'
# => 1.0
./goruby19 -e 'p Fil.exp(".")'
"/home/manveru/pkgbuilds/ruby-svn/src/trunk"
Read golf_prelude.c
для большего количества аккуратных вещей, скрывающихся.
Другое забавное дополнение в 1.9 функциональностях Proc является Proc#curry, который позволяет Вам поворачивать Proc, принимающий n аргументы в одно принятие n-1. Здесь это объединено с Proc# === подсказка, которую я упомянул выше:
it_is_day_of_week = lambda{ |day_of_week, date| date.wday == day_of_week }
it_is_saturday = it_is_day_of_week.curry[6]
it_is_sunday = it_is_day_of_week.curry[0]
case Time.now
when it_is_saturday
puts "Saturday!"
when it_is_sunday
puts "Sunday!"
else
puts "Not the weekend"
end
Функция Symbol#to_proc, которую обеспечивают направляющие, действительно прохладна.
Вместо
Employee.collect { |emp| emp.name }
можно записать:
Employee.collect(&:name)
Одно заключительное одно - в рубине, можно использовать любой символ, Вы хотите разграничить строки. Возьмите следующий код:
message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"
, Если Вы не хотите выходить из двойных кавычек в строке, можно просто использовать различный разделитель:
contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]
, А также избегающий необходимости разделители Escape, можно использовать эти разделители для более хороших многострочных строк:
sql = %{
SELECT strings
FROM complicated_table
WHERE complicated_condition = '1'
}
Я нахожу, что использование команда define_method динамично генерирует методы, чтобы быть довольно интересным и не также известный. Например:
((0..9).each do |n|
define_method "press_#{n}" do
@number = @number.to_i * 10 + n
end
end
вышеупомянутый код использует команду 'define_method' для динамичного создания методов "press1" через "press9". Скорее затем вводя все 10 методов, которые по существу содержат тот же код, определить команда метода используется для генерации этих методов на лету по мере необходимости.
Модуля, которые объявляются как module_function, создадут копии себя как частный методы экземпляра в классе, который включает Модуль:
module M
def not!
'not!'
end
module_function :not!
end
class C
include M
def fun
not!
end
end
M.not! # => 'not!
C.new.fun # => 'not!'
C.new.not! # => NoMethodError: private method `not!' called for #<C:0x1261a00>
, Если Вы используете module_function без каких-либо аргументов, тогда какие-либо методы модуля, который прибывает после того, как module_function оператор автоматически станет module_functions сами.
module M
module_function
def not!
'not!'
end
def yea!
'yea!'
end
end
class C
include M
def fun
not! + ' ' + yea!
end
end
M.not! # => 'not!'
M.yea! # => 'yea!'
C.new.fun # => 'not! yea!'
Предупреждение: за этот объект проголосовали № 1 Самый Ужасающий Взлом 2008 , таким образом используйте с осторожностью. На самом деле избегайте его как чумы, но это - несомненно Скрытый Ruby.
Когда-нибудь хотят суперсекретный оператор квитирования для некоторой уникальной операции в Вашем коде? Как то, чтобы играть в гольф кода? Попробуйте операторы как - ~ + ~ - или <---, Которые длятся, каждый используется в примерах для инвертирования порядка объекта.
я не имею никакого отношения Проект Superators вне восхищения им.
Class.new()
Создают новый класс во время выполнения. Аргументом может быть класс для получения из, и блок является телом класса. Вы могли бы также хотеть посмотреть const_set/const_get/const_defined?
для получения нового класса, правильно зарегистрированного, так, чтобы inspect
распечатал имя вместо числа.
Не что-то, в чем Вы нуждаетесь каждый день, но довольно удобный, когда Вы делаете.
Хеши со значениями по умолчанию! В данном случае это массив.
parties = Hash.new {|hash, key| hash[key] = [] }
parties["Summer party"]
# => []
parties["Summer party"] << "Joe"
parties["Other party"] << "Jane"
Очень полезно при метапрограммировании.
создать массив последовательных чисел:
x = [*0..5]
устанавливает x равным [0, 1, 2, 3, 4, 5]
Я опаздываю на вечеринку, но:
Вы можете легко взять два массива одинаковой длины и превратить их в хеш, один из которых содержит ключи, а другой - значения:
a = [:x, :y, :z]
b = [123, 456, 789]
Hash[a.zip(b)]
# => { :x => 123, :y => 456, :z => 789 }
(Это работает, потому что Array # zip «застегивает» значения из двух массивов:
a.zip(b) # => [[:x, 123], [:y, 456], [:z, 789]]
И Hash [] может принимать именно такой массив. Я видел, как люди тоже делали это:
Hash[*a.zip(b).flatten] # unnecessary!
Что дает тот же результат, но splat и flatten совершенно не нужны - может, их не было в прошлом?)
Использовать объект Range в качестве бесконечного ленивого списка:
Inf = 1.0 / 0
(1..Inf).take(5) #=> [1, 2, 3, 4, 5]
Подробнее здесь: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite- range-in-ruby /
Булевы операторы для небулевых значений.
&&
и ||
Оба возвращают значение последнего вычисленного выражения.
Вот почему || =
обновит переменную значением, возвращаемым выражением справа, если переменная не определена. Это явно не задокументировано, но общеизвестно.
Однако && =
не так широко известен.
string &&= string + "suffix"
эквивалентен
if string
string = string + "suffix"
end
Это очень удобно для деструктивных операций, которые не должны продолжить, если переменная не определена.
Двоичный "рубин" (по крайней мере, МРТ) поддерживает множество переключателей, что сделало perl one-liners весьма популярным.
Значимые:
put
s в конце каждой итерации цикла-w Некоторые примеры:
# Print each line with its number:
ruby -ne 'print($., ": ", $_)' < /etc/irbrc
# Print each line reversed:
ruby -lne 'puts $_.reverse' < /etc/irbrc
# Print the second column from an input CSV (dumb - no balanced quote support etc):
ruby -F, -ane 'puts $F[1]' < /etc/irbrc
# Print lines that contain "eat"
ruby -ne 'puts $_ if /eat/i' < /etc/irbrc
# Same as above:
ruby -pe 'next unless /eat/i' < /etc/irbrc
# Pass-through (like cat, but with possible line-end munging):
ruby -p -e '' < /etc/irbrc
# Uppercase all input:
ruby -p -e '$_.upcase!' < /etc/irbrc
# Same as above, but actually write to the input file, and make a backup first with extension .bak - Notice that inplace edit REQUIRES input files, not an input STDIN:
ruby -i.bak -p -e '$_.upcase!' /etc/irbrc
Не стесняйтесь гуглить "рубиновые однослойки" и "perl однослойки" для тонны более полезных и практичных примеров. По сути, это позволяет использовать рубин как достаточно мощную замену awk и sed.
Автовидифицирующий хэши в Ruby
def cnh # silly name "create nested hash"
Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
my_hash = cnh
my_hash[1][2][3] = 4
my_hash # => { 1 => { 2 => { 3 =>4 } } }
Это может быть чертовски удобно.
Fixnum#to_s(base)
может быть действительно полезен в некоторых случаях. Одним из таких случаев является генерация случайных (псевдо)уникальных токенов путем преобразования случайного числа в строку с использованием основания 36.
Токен длины 8:
rand(36**8).to_s(36) => "fmhpjfao"
rand(36**8).to_s(36) => "gcer9ecu"
rand(36**8).to_s(36) => "krpm0h9r"
Токен длины 6:
rand(36**6).to_s(36) => "bvhl8d"
rand(36**6).to_s(36) => "lb7tis"
rand(36**6).to_s(36) => "ibwgeh"
Вау, никто не упомянул оператор триггера:
1.upto(100) do |i|
puts i if (i == 3)..(i == 15)
end
Ruby имеет механизм call/cc , позволяющий один свободно скачкообразно двигаться вверх и вниз по стеку.
Простой пример следует. Это, конечно, не, как можно было бы умножить последовательность в рубине, но он демонстрирует, как можно было бы использовать call/cc для достижения стека для закорачивания алгоритма. В этом случае мы рекурсивно умножаем список чисел, пока мы или не видели каждое число, или мы видим нуль (два случая, где мы знаем ответ). В нулевом случае мы можем быть произвольно глубокими в списке и оконечными.
#!/usr/bin/env ruby
def rprod(k, rv, current, *nums)
puts "#{rv} * #{current}"
k.call(0) if current == 0 || rv == 0
nums.empty? ? (rv * current) : rprod(k, rv * current, *nums)
end
def prod(first, *rest)
callcc { |k| rprod(k, first, *rest) }
end
puts "Seq 1: #{prod(1, 2, 3, 4, 5, 6)}"
puts ""
puts "Seq 2: #{prod(1, 2, 0, 3, 4, 5, 6)}"
Вы видите вывод здесь:
Для более сложного примера, показывающего продолжения, перемещающие другое направление в стек, считайте источник в Генератор .
Как насчет того, чтобы открыть файл на основе ARGV [0]?
readfile.rb:
$<.each_line{|l| puts l}
ruby readfile.rb testfile.txt
Это - большой ярлык для записи одноразовых сценариев. Существует целая путаница предварительно определенных переменных, о которых не знает большинство людей. Используйте их мудро (чтение: не замусорьте кодовую базу, которую Вы планируете поддержать с ними, это может стать грязным).